Im having troubles with an application. I have a MVC application that query a database (and some webservices) and return me information in JSON. In My Local Machine works like a charm but when I upload it to the webserver I get this error:
"Error getting value from '_owner' on 'System.Data.Objects.DataClasses.RelationshipManager'."
(You can see the whole error page in http://canedroid.com/mvc/api/requests/getlastcheckins)
I tried disabling proxies and lazy loading with:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.Configuration.LazyLoadingEnabled = false;
base.Configuration.ProxyCreationEnabled = false;
}
And nothing happens.
Model:
namespace CaneDroid.MVCApp.Models
{
public class CaneDroidContext : DbContext,ICaneDroidDataSource
{
public CaneDroidContext()
: base("DefaultConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.Configuration.LazyLoadingEnabled = false;
base.Configuration.ProxyCreationEnabled = false;
}
public DbSet<Checkin> mdlCheckins { get; set; }
public DbSet<configAndroid> configAndroid { get; set; }
IQueryable<Checkin> ICaneDroidDataSource.Checkins
{
get { return mdlCheckins; }
}
}
public class Checkin
{
public Checkin()
{
visto = false;
}
[Key,DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
[Required]
public virtual string fsqCheckinId { get; set; }
public virtual string text { get; set; }
public virtual string usrId { get; set; }
public virtual string usrFrstName { get; set; }
public virtual string usrLstName { get; set; }
public virtual string venueId { get; set; }
public virtual string venueName { get; set; }
public virtual string venueAddress { get; set; }
public virtual string venueCrossStreet { get; set; }
public virtual string venueLat { get; set; }
public virtual string venueLng { get; set; }
public virtual string venueCity { get; set; }
public virtual bool visto { get; set; }
}
public class configAndroid
{
[Key, DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
public string key { get; set; }
public bool value { get; set; }
}
}
Action in controller:
public R getLastCheckins()
{
var responseJson = R.getLastCheckins(db);
return responseJson;
}
public static R getLastCheckins(CaneDroidContext db)
{
var cache = db.mdlCheckins.OrderByDescending(q => q.Id).Take(10);
return new R(cache, null, null, null, null, null);
}
I don't know what else can I do.
Nevermind. I found the solution. The problem was the Context variable.
private static CaneDroidContext db = new CaneDroidContext();
When I modified it and made it static everything started to work normally.
Related
I am creating ASP.Net MVC WebApi to share my data to bank. In this regard i have created an SQL View bit when i am testing my WebApi it is giving an 'System.OutOfMemoryException' error because i have more the 1 million record in SQL View.
My Code is given below:-
This is my controller
public class InvoiceController : ApiController
{
public IEnumerable<VBank_invoice> Get()
{
using (kmcEntities entities = new kmcEntities())
{
return entities.VBank_invoice.ToList();
}
}
public VBank_invoice Get(string consumer)
{
using (kmcEntities entities = new kmcEntities())
{
return entities.VBank_invoice.FirstOrDefault(e => e.consumer_no == consumer);
}
}
}
My SQL View Class
public partial class VBank_invoice
{
public int sno { get; set; }
public string consumer_no { get; set; }
public string consumer_name { get; set; }
public string consumer_address { get; set; }
public string billing_month { get; set; }
public Nullable<decimal> current_Charges { get; set; }
public Nullable<decimal> outstanding_Arrears { get; set; }
public Nullable<decimal> Arrears_15 { get; set; }
public Nullable<decimal> part_payment_arrears { get; set; }
public string billing_period_code { get; set; }
public string consumer_checkdigit { get; set; }
public Nullable<System.DateTime> due_date { get; set; }
}
This is my Model.Context.cs File
public partial class kmcEntities : DbContext
{
public kmcEntities()
: base("name=kmcEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<VBank_invoice> VBank_invoice { get; set; }
}
I believe you need to be serialize object model using the select query.
public class InvoiceController : ApiController
{
public IEnumerable<VBank_invoice> Get()
{
using (kmcEntities entities = new kmcEntities())
{
return entities.VBank_invoice.select(m => new {
m.sno, m.consumer_no,m.consumer_name, m.consumer_address,
m.billing_month, m.current_Charges, m.outstanding_Arrears,
m.Arrears_15, m.part_payment_arrears, m.billing_period_code,
m.consumer_checkdigit, m.due_date }).ToList();
}
}
}
I have relationship one to one
public class Book
{
public int BookId { get; set; }
public string Name { get; set; }
public string Annotation { get; set; }
public virtual File File { get; set; }
public int? SeriesId { get; set; }
public DateTime UploadDate { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Author> Authors { get; set; }
public virtual ICollection<Genre> Genres { get; set; }
public virtual ICollection<Mark> Marks { get; set; }
public Book()
{
Comments = new List<Comment>();
Authors = new List<Author>();
Genres = new List<Genre>();
}
}
public class File
{
[Key,ForeignKey("Book")]
public int BookId { get; set; }
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Content { get; set; }
public virtual Book Book { get; set; }
}
And I want to transfer data to classes:
public class BookDO
{
public int BookId { get; set; }
public string Name { get; set; }
public string Annotation { get; set; }
public virtual FileDO File { get; set; }
}
public class FileDO
{
public int BookId { get; set; }
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Content { get; set; }
public virtual BookDO Book { get; set; }
}
in such way:
var books = Database.Books.GetAll().ToList();
Mapper.Initialize(cf => cf.CreateMap<Book, BookDO>());
return Mapper.Map<List<Book>, List<BookDO>>(books);
but i'm getting Missing type map configuration or unsupported mapping.
Mapping types:
File -> FileDO
Domain.File -> BusinessLogic.Data_Objects.FileDO
Maybe i need to initialize one more mapper to map File to FileDO or modify existing mapper configuration? help me please.
Yes, you also need to create a map for File -> FileDo. This map must be configured for the same mapper as used for Book -> BookDo.
It is good practice to wrap your mapping configuration into an AutoMapper.Profile:
using AutoMapper;
public class BookMappingProfile: Profile {
public BookMappingProfile() {
CreateMap<Book, BookDo>();
CreateMap<File, FileDo>();
}
}
And then initialize the mapper with these profiles:
Mapper.Initialize(cfg => {
cfg.AddProfile<BookMappingProfile>();
cfg.AddProfile<MyOtherProfile>();
});
Most of the tutorials for MVC with Entity Framework are centered around Code-First, where you write classes for generating the model. This gives the advantage of control and Migrations, but I think it lack overview. I would therefore prefer to create the model using the graphical designer, but I cannot see how or if data migrations work in this context. It seems, that when I change the model (with data in the database), all the data is deleted in all tables.
Is there a way around this?
How can I do validation when using Model-First? Partial classes?
you may use the global validation beside mvc validation
example :
public class ValidationCriteria
{
public ValidType Type { get; set; }
public ValidRange Range { get; set; }
public ValidFormat Format { get; set; }
public ValidIsNull IsNull { get; set; }
public ValidCompare Compare { get; set; }
public ValidDB DB { get; set; }
public string Trigger { get; set; }
public Dictionary<string, ValidationCriteria> Before { get; set; }
public string After { get; set; }
public class ValidDB
{
public string functionName { get; set; }
public object[] param { get; set; }
public object functionClass { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidCompare
{
public string first { get; set; }
public string second { get; set; }
public string compareOperator { get; set; }
public string compareValue { get; set; }
public string msg { get; set; }
public bool check = false;
}
public ValidationCriteria()
{
this.Range = new ValidRange();
this.Format = new ValidFormat();
this.IsNull = new ValidIsNull();
this.Type = new ValidType();
this.Compare = new ValidCompare();
this.DB = new ValidDB();
this.Trigger = "blur";
this.Before = new Dictionary<string, ValidationCriteria>();
this.After = "";
}
public class ValidType
{
// checking element is integer.
public bool isInt { get; set; }
// checking element is decimal.
public bool isDecimal { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidRange
{
public long min { get; set; }
public long max { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidFormat
{
public bool isEmail { get; set; }
public string regex { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidIsNull
{
public string nullDefaultVal { get; set; }
public string msg { get; set; }
public bool check = false;
}
}
Meanwhile you may use validation part in your controller
Example :
private bool validateMaintainanceManagement(MaintainanceCRUD.Maintainance model, bool edit = false, bool ServerValidation = true)
{
bool ValidModel = false;
Dictionary<string, ValidationCriteria> validCriteria = new Dictionary<string, ValidationCriteria>();
#region maintainTitle Criteria
ValidationCriteria maintainTitle = new ValidationCriteria();
maintainTitle.IsNull.msg = Resources.Home.ErrmaintainTitle;
maintainTitle.IsNull.check = true;
maintainTitle.IsNull.nullDefaultVal = "-1";
//maintainTitle.Trigger = "change"; // this may trigger if you are using dropdown
validCriteria.Add("maintainTitle", maintainTitle);
#endregion
I found a way to use Automapper for Language mapping based on the active Culture.
The question is if it's possible to build a generic Resolver to map all the models that use the Resolver.
In this Case, the models to map have always the same properties, Id and Name (including the language properties Name_PT, Name_FR and Name_EN):
// MODELS
public class MakeDto
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
public string Name_PT { get; set; }
public string Name_FR { get; set; }
public string Name_EN { get; set; }
}
public class MakeViewModel
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
}
public class ModelDto
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
public string Name_PT { get; set; }
public string Name_FR { get; set; }
public string Name_EN { get; set; }
}
public class ModelViewModel
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
}
public class FuelDto
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
public string Name_PT { get; set; }
public string Name_FR { get; set; }
public string Name_EN { get; set; }
}
public class FuelViewModel
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
}
// AUTOMAPPER PROFILE
public class DtoToViewModelMappingProfile : Profile
{
public override string ProfileName
{
get { return "DtoToViewModelMappings"; }
}
protected override void Configure()
{
CreateMaps();
}
private static void CreateMaps()
{
Mapper.CreateMap<ModelDto, ModelViewModel>();
Mapper.CreateMap<MakeDto, MakeViewModel>()
.ForMember(dest => dest.Name, opt => opt.ResolveUsing<CultureResolver>());
Mapper.CreateMap<FuelDto, FuelViewModel>();
}
public class CultureResolver : ValueResolver<MakeDto, string>
{
protected override string ResolveCore(MakeDto makeDto)
{
switch(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToUpperInvariant())
{
case "FR":
return makeDto.Name_FR;
case "EN":
return makeDto.Name_EN;
}
return makeDto.Name_PT;
}
}
}
Thanks.
You can extract an interface like below:
public interface ILocalizable
{
string Name { get; set; }
string Name_PT { get; set; }
string Name_FR { get; set; }
string Name_EN { get; set; }
}
public class FuelDto : ILocalizable
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
public string Name_PT { get; set; }
public string Name_FR { get; set; }
public string Name_EN { get; set; }
}
Then tune your resolver like below:
public class CultureResolver : ValueResolver<ILocalizable, string>
{
protected override string ResolveCore(ILocalizable dto)
{
switch(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToUpperInvariant())
{
case "FR":
return dto.Name_FR;
case "EN":
return dto.Name_EN;
}
return dto.Name_PT;
}
}
public class ParikshaContext :DbContext
{
public ParikshaContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ParikshaContext>());
}
public DbSet<UserDetail> UserDetails { get; set; }
public DbSet<Standard> Standards { get; set; }
public DbSet<Subject> Subjects { get; set; }
public DbSet<QuestionDescriptor> QuestionDescriptors { get; set; }
public DbSet<QuestionBrief> QuestionBriefs { get; set; }
public DbSet<QuestionCustom> QuestionCustoms { get; set; }
public DbSet<QuestionChoice> QuestionChoices { get; set; }
public DbSet<QuestionMatch> QuestionMatches { get; set; }
public DbSet<Test> Tests { get; set; }
public DbSet<Test_Question> Test_Questions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<QuestionCustom>().ToTable("Custom");
modelBuilder.Entity<QuestionBrief>().ToTable("Brief");
modelBuilder.Entity<QuestionMatch>().ToTable("Match");
modelBuilder.Entity<QuestionChoice>().ToTable("Choice");
}
}
public class QuestionDescriptor
{
public int QuestionDescriptorId { get; set; }
public int StandardId { get; set; }
[ForeignKey("StandardId")]
public virtual Standard Standard { get; set; }
public int SubjectId { get; set; }
[ForeignKey("SubjectId")]
public virtual Subject Subject { get; set; }
public int Rating { get; set; }
public int Difficulty { get; set; }
public DateTime DateOfCreation{get;set;}
public int UserDetailId { get; set; }
[ForeignKeyAttribute("UserDetailId")]
public virtual UserDetail Creator { get; set; }
}
public class QuestionBrief : QuestionDescriptor
{
public String QuestionText { get; set; }
public String Answer { get; set; }
//true for fill in the blanks and false for a loing answers
public bool Short { get; set; }
}
public class Standard
{
public int StandardId { get; set; }
public String StandardName { get; set; }
}
public class Subject
{
public int SubjectId { get; set; }
public String SubjectName { get; set; }
public String SubjectCategory { get; set; }
// public int StandardId { get; set; }
// [ForeignKey("StandardId")]
// public virtual Standard Standard { get; set; }
}
public class Test
{
public int TestID { get; set; }
public DateTime DateOfCreation { get; set; }
public String StandardName { get; set; }
public String SubjectName { get; set; }
public String SubjectCategory { get; set; }
// public int UserDetailId { get; set; }
// [ForeignKey("UserDetailId")]
// public virtual UserDetail Creator { get; set; }
}
public class Test_Question
{
public int Test_QuestionID { get; set; }
public int TestId { get; set; }
[ForeignKey("TestId")]
public virtual Test Test { get; set; }
public int QuestionDescriptorId { get; set; }
[ForeignKey("QuestionDescriptorId")]
public virtual QuestionDescriptor Question { get; set; }
}
public class UserDetail
{
public int UserDetailId { get; set; }
[Required]
[MaxLength(10, ErrorMessage = "UserName must be 10 characters or less"), MinLength(5)]
public String Name { get; set; }
[Required]
public String Password { get; set; }
public String UserRole { get; set; }
public DateTime DateOfCreation{ get; set;}
}
//Match,Custom,Choice classes have been omitted for lack of space (which sounds stupid when i look at the amount of code i have pasted )
I have two problems:-
I cant get a foreign key relation between standard and subjects,it says the relation will cause several cascade delete paths...
if I make a foreign key rlation between test and usedetail it gives me the above problem for mapping the tst_question table .
Also since I am new to EF code first ,please point out my mistakes.all help and disccussion is welcome.
By default EF will create foreign keys will cascade delete. In your model if you delete a Standard there are multiple paths to delete the QuestionDescriptor.
Standard -> QuestionDescriptor
and
Standard -> Subject -> QuestionDescriptor
That is why SQL server does not allow you to do this. See this answer for more details
What you can do is explicitly tell EF to create foreign keys without cascade delete. But this may create data integrity problems. So make sure you understand the consequences.
What you can do is configure the relationships using fluent API with WillCascadeOnDelete(false).
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//other mappings
modelBuilder.Entity<Subject>()
.HasRequired(subject => subject.Standard).WithMany()
.HasForeignKey(subject => subject.StandardId)
.WillCascadeOnDelete(false);
}