I have configured my connection to DB as follows:
Web.config
<add name="MyContext" providerName="System.Data.SqlClient" connectionString="Data Source=MyServer;Initial Catalog=MyDB;User id=MyId;Password=MyPassword; MultipleActiveResultSets=true" />
Then I have my class to create context in order to access Database
public class MyContext: DbContext
{
public MyContext() : base("MyContext")
{
Database.SetInitializer<Models.MyContext>(null);
}
public DbSet<MyModel> MyTable { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Then I have my DB with table 'MyTable', which is a history table, so every day at 6:00 I am inserting data from another table, finally I will have results like this
Id | Date
-----------------------------
1 | 2018-05-30 16:01:00.332
1 | 2018-05-31 14:21:03.456
1 | 2018-06-01 11:45:01.316
2 | 2018-05-30 21:44:00.544
2 | 2018-05-31 22:45:00.987
2 | 2018-06-01 23:46:00.769
So now in MyController.cs
public IQueryable<MyModel> GetData(string Id)
{
var result = MyContext.MyTable.AsQueryable();
return result.Where(w => w.Id == Id).toList();
}
I am trying to return all rows for Id = 1, on debugging when I set a breakpoint in the return statement, it returns the same row, for every record.
Id | Date
-----------------------------
1 | 2018-05-30 16:01:00.332
1 | 2018-05-30 16:01:00.332
1 | 2018-05-30 16:01:00.332
Edit: I add MyModel class as you requested
public class MyModel
{
[Index(IsUnique = false)]
public int Id { get; set; }
public DateTime Date{ get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
public string Field5 { get; set; }
public string Field6 { get; set; }
public string Field7 { get; set; }
public DateTime? Field8 { get; set; }
public string Field9 { get; set; }
public string Field10 { get; set; }
public string Field11 { get; set; }
public string Field12 { get; set; }
public string Field13 { get; set; }
public string Field14 { get; set; }
public string Field15 { get; set; }
public string Field16 { get; set; }
public string Field17 { get; set; }
public string Field18 { get; set; }
public string Field19 { get; set; }
public int? Field20 { get; set; }
public string Field21 { get; set; }
public int? Field22 { get; set; }
public int? Field23 { get; set; }
public int? Field24 { get; set; }
public string Field25 { get; set; }
public string Field26 { get; set; }
public string Field27 { get; set; }
public int Field28 { get; set; }
public string Field29 { get; set; }
public string Field30 { get; set; }
public string Field31 { get; set; }
public string Field32 { get; set; }
public string Field33 { get; set; }
public DateTime? Field34 { get; set; }
}
Can you help me to figure out what's going on?
Thanks.
[Index(IsUnique = false)]
public int Id { get; set; }
This does not prevent Id from being the Primary Key. If it did you would have seen another error, EF demands a PK on your classes.
You have only added an extra Index on the Id column. Not removed the PK constraint.
So our first suspicions appear to be right, you load a bunch of records with duplicate PK values in memory. When you try SaveChanges() you will get an error or lose data.
A simple fix would look like
public class MyModel
{
[Key]
public int ModelId { get; set; } // auto filled, ignore where you don't need it
//[Index(IsUnique = false)] -- not needed
public int Id { get; set; }
public DateTime Date{ get; set; }
...
Related
I'm using EF code first migrations in MVC5 with SQL Server.
I created a post method, I'm posting DTO data from the client and its all fine i believe, but when i try to save the data to the db i get this invalid column name exception on a foreign key property.
This is the first time i actually counter this error. I checked other questions and most answers were related to the [ForeignKey] data annotation but i think i implemented it the right way
This is the Model
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public bool Approved { get; set; }
}
This is the controller ActionResult method
[HttpPost]
public ActionResult AddServiceProvider(ServiceProviderDTO serviceProvider)
{
bool isInDb = _context.ServiceProviders.Any(s => s.Name == serviceProvider.Name) ? true : false;
//var serviceProviderInDb = _context.ServiceProviders.Where(s => s.Name == serviceProvider.Name).FirstOrDefault();
var newServiceProvider = new ServiceProvider();
if (isInDb == false)
{
newServiceProvider = new ServiceProvider
{
Id = Guid.NewGuid(),
Name = serviceProvider.Name,
PhoneNumber = serviceProvider.PhoneNumber,
YearsOfExperiance = serviceProvider.YearsOfExperiance,
Nationality = serviceProvider.Nationality,
CategoryId = serviceProvider.CategoryId,
Active = true,
Approved = serviceProvider.Approved == null ? false : serviceProvider.Approved.Value
};
_context.ServiceProviders.Add(newServiceProvider);
_context.SaveChanges();
}
return RedirectToAction("Index", "Home");
}
The error occurs on _context.SaveChanges();
It states that CategoryId is an invalid column name
This is not the first time that i use code first migrations and i never came across this error before so i really have no idea why this happens!
I would have the model like this.
The ForeignKey attribute belong to the Category property
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
public int CategoryId { get; set; }
[ForeignKey("CategoryId")]
public Category Category { get; set; }
public bool Approved { get; set; }
}
you need delete this property public int CategoryId { get; set; }
your property public Category Category { get; set; } is the ForeignKey and add the DataAnnotations [ForeignKey("CategoryId")]
it would look like this
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public bool Approved { get; set; }
}
I have a statement in one of my entities which uses a foreign key to return an IEnumerable<CustomField>.
I have used LINQ in my repository to test the below method to see if it works and it does. But when I use the foreign key reference in the entity it returns null. Am I missing something here? How can I use a foreign key to gain access to the data in another entity.
Invoice entity:
[Table("vwinvoice")]
public class Invoice
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int Sys_InvoiceID { get; set; }
[DisplayName("Inc.In Turnover")]
public bool Turnover { get; set; }
public int FK_StatusID { get; set; }
[DisplayName("Invoice No.")]
public string InvoiceNumber { get; set; }
[DisplayName("Invoice Date")]
public DateTime InvoiceDate { get; set; }
[DisplayName("Document Type")]
public string DocType { get; set; }
[DisplayName("Supplier Invoice No.")]
[Column("SupplierInvoiceNumber")]
public string SuppInvNumber { get; set; }
public int FK_SupplierID { get; set; }
[DisplayName("Account Number")]
public string AccountNumber { get; set; }
[DisplayName("Order Number")]
public string OrderNumber { get; set; }
[DisplayName("Order Date")]
public DateTime? OrderDate { get; set; }
[DisplayName("Currency Code_Doc")]
public string CurrencyCode_Doc { get; set; }
[DisplayName("Net Amount_Doc")]
public decimal? NetAmount_Doc { get; set; }
[DisplayName("VAT Amount_Doc")]
public decimal? VATAmount_Doc { get; set; }
[DisplayName("Gross Amount_Doc")]
[Required]
public decimal? GrossAmount_Doc { get; set; }
[DisplayName("Currency Code_Home")]
public string CurrencyCode_Home { get; set; }
[DisplayName("Net Amount_Home")]
public decimal? NetAmount_Home { get; set; }
[DisplayName("VAT Amount_Home")]
public decimal? VATAmount_Home { get; set; }
[DisplayName("Gross Amount_Home")]
public decimal? GrossAmount_Home { get; set; }
[DisplayName("Payment Reference")]
public string PaymentReference { get; set; }
[DisplayName("Supplier")]
public string AccountName { get; set; }
[DisplayName("Status")]
public string StatusName { get; set; }
[DisplayName("Auditor Comments")]
public string AuditorComments { get; set; }
[DisplayName("Reviewer Comments")]
public string ReviewerComments { get; set; }
[DisplayName("Data Source")]
[Required]
public string DataOrigin { get; set; }
public int DetailLineCount { get; set; }
public IEnumerable<CustomField> ClientData {
get {
//Use the CustomFields foreign key to gain access to the data returns null.
return GetCustomFieldData(this.CustomFields.Select(r => r));
}
}
private IEnumerable<CustomField> GetCustomFieldData(IEnumerable<Entities.CustomFields> enumerable) {
return (from f in enumerable
select new CustomField {
Name = f.FK_CustomHeader,
Value = f.Value
});
}
//Custom Field Additions
public virtual ICollection<CustomFields> CustomFields { get; set; }
}
CustomFields entity:
[Table("tblCustomFields")]
public class CustomFields
{
[Key]
public int ID { get; set; }
public int? FK_SysInvoiceID { get; set; }
[StringLength(255)]
public string FK_CustomHeader { get; set; }
[StringLength(255)]
public string Value { get; set; }
public virtual Invoice Invoices { get; set; }
public virtual CustomFieldHeaders CustomFieldHeaders { get; set; }
}
I also cannot place a breakpoint in the get statement to see what happens, why is this? It just skips over the breakpoint whenever I try to return a list of Invoices, which can be seen here:
public IQueryable<Invoice> Invoices
{
get
{
var x = _ctx.Invoices.ToList();
return _ctx.Invoices;
}
}
You are using the virtual keyword when declaring your CustomFields property. As such it will be lazy loaded. If you want the property to be populated once returned from the repository you will need to explicitly Include the table in your method:
var x = _ctx.Invoices.Include(i => i.CustomFields).ToList();
return _ctx.Invoices;
Or you can remove the virtual keyword and the property will always be populated, with the consequent performance hit of the database join and the extra data being returned whenever you access Invoices.
I have an entity and I'm trying to add it to a collection in two different entities.
What I want to achieve is something like
[1] => DomainUser { name = "bob" }
DomainGroup.Users = [ 1 ]
LocalGroup.Users = [ 1 ]
When I try to save changes, however, I get Multiplicity constraint violated. The role 'DomainGroup_Users_Source' of the relationship 'Server.DomainTools.Models.DomainGroup_Users' has multiplicity 1 or 0..1.
Here's my entities:
This is where I feel my issues lies: DomainUser
public class DomainUser
{
public string Name { get; set; }
public int Id { get; set; }
public string DisplayName { get; set; }
public string DistinguishedName { get; set; }
public int AdminCount { get; set; }
public int PwdLastSet { get; set; }
public string AdsPath { get; set; }
public int LastLogon { get; set; }
public int LastLogoff { get; set; }
public int LockoutTime { get; set; }
public int AccountExpires { get; set; }
public int BadPwdCount { get; set; }
public int LogonCount { get; set; }
}
And here are the two entities that I'm trying to add DomainUser to: DomainGroup and LocalGroup
public class DomainGroup
{
public string Name { get; set; }
public List<DomainUser> Users { get; set; }
public List<DomainGroup> Groups { get; set; }
public string DistinguishedName { get; set; }
public int Id { get; set; }
public DomainGroup()
{
Users = new List<DomainUser>();
Groups = new List<DomainGroup>();
}
}
public class LocalGroup
{
public string Name { get; set; }
public int Id { get; set; }
public string DisplayName { get; set; }
public string Comment { get; set; }
public List<LocalUser> LocalUsers { get; set; }
public List<DomainUser> DomainUsers { get; set; }
public List<DomainGroup> DomainGroups { get; set; }
public List<LocalGroup> LocalGroups { get; set; }
public LocalGroup()
{
LocalUsers = new List<LocalUser>();
LocalGroups = new List<LocalGroup>();
DomainUsers = new List<DomainUser>();
DomainGroups = new List<DomainGroup>();
}
}
I have a table that looks like this :-
CategoryId | QuestionId
-----------------------
1 | 2
1 | 3
3 | 2
4 | 3
I need to pull out all of the Questions that are not in use by a specific category. so for eg, CategoryID = 1.
The result should be that there are no questions to display.
Anyone know the best way to do this? so far i've not got anywhere with it.
EDIT **
public partial class FAQ
{
public FAQ()
{
this.FAQCategoriesFAQs = new HashSet<FAQCategoriesFAQ>();
}
public int Id { get; set; }
public string Question { get; set; }
public string Answer { get; set; }
public bool IsVisible { get; set; }
public Nullable<System.DateTime> DateLastUpdated { get; set; }
public System.DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public virtual ICollection<FAQCategoriesFAQ> FAQCategoriesFAQs { get; set; }
}
public partial class FAQCategory
{
public FAQCategory()
{
this.FAQCategoriesFAQs = new HashSet<FAQCategoriesFAQ>();
}
public int Id { get; set; }
public string Name { get; set; }
public int DomainId { get; set; }
public Nullable<System.DateTime> DateLastUpdated { get; set; }
public System.DateTime DateCreated { get; set; }
public bool IsDeleted { get; set; }
public int SortOrder { get; set; }
public virtual Domain Domain { get; set; }
public virtual ICollection<FAQCategoriesFAQ> FAQCategoriesFAQs { get; set; }
}
public partial class FAQCategoriesFAQ
{
public int FAQCategoryId { get; set; }
public int FAQId { get; set; }
public int SortOrder { get; set; }
public virtual FAQCategory FAQCategory { get; set; }
public virtual FAQ FAQ { get; set; }
}
If you have navigation property for categories in Question entity:
db.Questions.Where(q => !q.Categories.Any(c => c.Id == id))
UPDATE Thus your junction table differs a little bit from your original question :)
db.FAQs.Where(q => !q.FAQCategoriesFAQs.Any(qc => qc.FAQCategoryId == id))
Table 1: Articles
Table 2: ArticleCategories
how do I represent the relationship between the two tables which is a 1->1 relationship:
I can do the following, but I'm not sure it's the correct way :
public class Article
{
public int ArticleIndex { get; set; }
public int Category { get; set; }
public Guid User { get; set; }
public int Parent { get; set; }
public int Level { get; set; }
public int Order { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateExpires { get; set; }
public bool Show { get; set; }
public string Title { get; set; }
public string TitleHtml { get; set; }
public string Content { get; set; }
public string ContentHtml { get; set; }
public string ShortTitle { get; set; }
public ArticleCategory Category { get; set; }
}
public class ArticleCategory
{
public int CategoryIndex { get; set; }
public string Name { get; set; }
}
By convention, Code First expects an Id property for each class/table. Then you can do something like this:
public class Article
{
public int Id { get; set; }
public int ArticleIndex { get; set; }
public int Category { get; set; }
public Guid User { get; set; }
public int Parent { get; set; }
public int Level { get; set; }
public int Order { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateExpires { get; set; }
public bool Show { get; set; }
public string Title { get; set; }
public string TitleHtml { get; set; }
public string Content { get; set; }
public string ContentHtml { get; set; }
public string ShortTitle { get; set; }
public int ArticleCategoryId { get; set; }
public virtual ArticleCategory ArticleCategory { get; set; }
}
public class ArticleCategory
{
public int Id { get; set; }
public int CategoryIndex { get; set; }
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
Note the virtual keyword. EF Code First needs this so it can perform its magic behind the scenes.
Now, if you are working with an Article, you can get all it's category info by doing article.ArticleCategory, and if you have an ArticleCategory you can find out what article it refers to with articleCategory.Articles.Single().
For more info, see this article by Scott Gu:
http://weblogs.asp.net/scottgu/archive/2010/12/08/announcing-entity-framework-code-first-ctp5-release.aspx