I created
public class Video
{
public int Id { get; set; }
[MaxLength(50)]
public string Nom { get; set;}
public ICollection<Langue> Langue { get; set; }
}
public class Langue
{
public int LangueId { get; set; }
[Required]
public string Designation { get; set; }
public ICollection<Video> Video { get; set; }
}
Migration is ok and 3 tables are created, Video, Langue and
VideoLangue with 2 fields VideoId and LangueId
It’s a many to many relationship.
I want to entrer data in OnModelCreating
public class VideoDbContext : DbContext
{
public VideoDbContext(DbContextOptions<VideoDbContext> option) : base(option)
{
}
public DbSet<Video> Video { get; set; }
public DbSet<Langue> Langue { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var langFR = new Langue() { LangueId = 1, Designation = "Français" };
var langIT = new Langue() { LangueId = 2, Designation = "Italien" };
var langCH = new Langue() { LangueId = 3, Designation = "Chinois" };
var langAN = new Langue() { LangueId = 4, Designation = "Anglais" };
modelBuilder.Entity<Video>().HasData(
new Video() { Id = 1, Nom = "007", Langue = new List<Langue> { langFR,langCH,langIT } }
);
When i do the migration i have this error
The seed entity for entity type 'Video' cannot be added because it has the navigation 'Langue' set. To seed relationships, add the entity seed to 'VideoLangue (Dictionary<string, object>)' and specify the foreign key values {'VideoId'}. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the involved property values.
According to this error i use an other way
i create a VideoLangue Class
public class VideoLangue
{
public int VideoId { get; set; }
public int LangueId { get; set; }
}
I modify the VideoContext
public class VideoDbContext : DbContext
{
public VideoDbContext(DbContextOptions<VideoDbContext> option) : base(option)
{
}
public DbSet<Video> Video { get; set; }
public DbSet<Langue> Langue { get; set; }
public DbSet<VideoLangue> VideoLangue { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Langue>().HasData(
//remplissage langue
new Langue() { LangueId = 1, Designation = "Français" },
new Langue() { LangueId = 2, Designation = "Italien" },
new Langue() { LangueId = 3, Designation = "Chinois" },
new Langue() { LangueId = 4, Designation = "Anglais" }
);
modelBuilder.Entity<Video>().HasData(
new Video() { Id = 1, Nom = "007}
);
modelBuilder.Entity<VideoLangue>()
.HasKey(o => new { o.VideoId, o.LangueId });
modelBuilder.Entity<VideoLangue>().HasData(
////remplissage VideoLangue
new VideoLangue() { VideoId = 1, LangueId = 1 },
new VideoLangue() { VideoId = 1, LangueId = 3 },
new VideoLangue() { VideoId = 1, LangueId = 4 }
);
When i do the migration i have
Cannot use table 'VideoLangue' for entity type 'VideoLangue (Dictionary<string, object>)' since it is being used for entity type 'VideoLangue' and potentially other entity types, but there is no linking relationship. Add a foreign key to 'VideoLangue (Dictionary<string, object>)' on the primary key properties and pointing to the primary key on another entity typed mapped to 'VideoLangue'.
How can we put data on langue via OnModelreating
Do you have an idea ?
Thank you
Related
I get this error in my .NET Core 3.1 app:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_DiaryDiaryEntry". The conflict occurred in database "xxxxxx", table "dbo.Diaries", column 'Id'.
I can't see anything wrong with the tables themselves.
public partial class Diaries
{
public long Id { get; set; }
public string CoverImage { get; set; }
public short Year { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public long ChildId { get; set; }
public Children Child { get; set; }
public ICollection<DiaryEntries> DiaryEntries { get; set; }
}
public partial class DiaryEntries
{
public long Id { get; set; }
public DateTime Date { get; set; }
public string Content { get; set; }
public long DiaryId { get; set; }
public Diaries Diary { get; set; }
public ICollection<Images> Images { get; set; }
}
My code? Probably an entirely different matter.
This is the code that generates the error.
[HttpPost("CreateYear/{id}")]
public async Task<IActionResult> CreateYearOfEntries([FromRoute] int id)
{
// The id is the ID of an existing diary
// Make sure the diary does exist first and that it belongs to the current logged-in user
var diary = _diaryRepository.Find(id);
if (diary == null) return NotFound();
var year = diary.Result.Year;
if (await _diaryEntryRepository.OwnerIsLoggedIn(LoggedInUser.ParentId, id))
{
var noOfDays = DateTime.IsLeapYear(year) ? 366 : 365;
var i = 0;
for (; i < noOfDays; i++)
{
var date = new DateTime(year, 1, 1).AddDays(i);
var newDiaryEntry = new DiaryEntries()
{
Content = " ",
Date = date,
DiaryId = diary.Id
};
await _diaryEntryRepository.Add(newDiaryEntry);
}
return Ok();
}
return NotFound();
}
public class DiaryEntryRepository : IDiaryEntryRepository
{
private readonly ApplicationDbContext _context;
public DiaryEntryRepository(ApplicationDbContext context)
{
_context = context;
}
public async Task<DiaryEntries> Add(DiaryEntries diaryEntry)
{
await _context.DiaryEntries.AddAsync(diaryEntry);
await _context.SaveChangesAsync();
return diaryEntry;
}
}
I have parent and childs nested tables.
Here is my model:
public class Categories
{
[Key]
public int CategoriesId { get; set; }
public int Order { get; set; }
public string CategoryName { get; set; }
public List<News> News { get; set; }
}
public class News
{
[Key]
public int NewsId { get; set; }
public int CategoriesId { get; set; }
public string Content { get; set; }
public DateTime Date { get; set; }
...
public List<Comments> Comments { get; set; }
public Categories Categories { get; set; }
}
public class Comments
{
[Key]
public int CommentsId { get; set; }
public int NewsId { get; set; }
public string Comment { get; set; }
...
public News News { get; set; }
}
public class NewsImages
{
[Key]
public int ImageId { get; set; }
public int NewsId { get; set; }
public string ImageUrl { get; set; }
public bool Cover { get; set;}
...
public News News { get; set; }
}
I'm trying to send it from ViewComponent to View;
public async Task<IViewComponentResult> InvokeAsync()
{
var group = _dbContext.Categories.Where(k => k.Order != 0).OrderBy(h => h.Order)
.Select(c => new
{
C = c,
N = c.News.OrderByDescending(n => n.Date).Take(5)
.Select(r => new
{
Y = r.Comments,
R = r.NewsImages.Where(rs => rs.Cover == true).FirstOrDefault()
})
});
var model = group
.Select(m => m.C);
return View(await model.ToListAsync()) ;
}
I am sure there are enough News records for every Category, But I get error :
ArgumentNullException: Value cannot be null. (Parameter 'source')
AspNetCore.Views_Shared_Components_IndexKategori_Default.ExecuteAsync() in Default.cshtml
var bp = k.News.FirstOrDefault();
if I use that code works fine :
var model = _dbContext.Categories
.Include(h => h.News).ThenInclude(h => h.Comments)
.Include(h => h.News).ThenInclude(h => h.NewsImages)
.Where(h => h.Order != 0)
.OrderBy(h => h.Order)
But when I use the code above, a few records appear for some categories, and some categories react as if there are no records.
Where am I making mistakes?
Thank you in advance for those who helped ..
Whenever you have a big LINQ statement that throws an exception, and you can't find where the exception comes form, translate the LINQ into smaller steps, and ToList() every step.
public async Task<IViewComponentResult> InvokeAsync()
{
// Temp code: small steps, ToList after every step
var a = dbContext.Categories.Where(category => category.Order != 0).ToList();
var b = a.OrderBy(category => category.Order).ToList();
var c = b.Select(category => new
{
Category = category,
News = category.News.OrderByDescending(news => news.Date)
.Take(5)
.ToList();
})
.ToList();
var d = c.Select(item => new
{
Category = item.Category,
NewsItems = item.News.Select(news => new
{
Comments = news.Comments,
Images = news.NewsImages.Where(newsImage => newsImage.Cover).ToList(),
})
.ToList(),
})
.ToList();
var e = d.Select(item => new
{
Category = item.Category,
NewsItems = item.NewsItems.Select(newsItem => new
{
Comments = newsItem.Comments,
Images = images.FirstOrDefault();
})
.ToList(),
})
.ToList();
// original code:
var group = _dbContext.Categories.Where...
}
I'm sure that your debugger will tell you which step is incorrect.
Data Model:
public class Product : RealmObject
{
[PrimaryKey,JsonProperty(PropertyName = "productId")]
public int ProductId { get; set; }
[JsonProperty(PropertyName = "parentId")]
public int ParentId { get; set; }
[JsonProperty(PropertyName = "productType")]
public string ProductType { get; set; }
}
Method used to add product to db:
public void AddSampleProduct(Product product)
{
var _realm = Realm.GetInstance();
using (var transaction = _realm.BeginWrite())
{
var entry = _realm.Add(product);
transaction.Commit();
}
}
Method used to retrieve product:
public Product GetProductById(int id)
{
Product product = null;
var _realm = Realm.GetInstance();
product = _realm.Find<Product>(id);
var p = _realm.Find<Product>(id);
return product;
}
Method to fetch list of products:
public List<Product> GetProductList()
{
List<Product> productList = new List<Product>();
var _realm = Realm.GetInstance();
productList = _realm.All<Product>().ToList();
return productList;
}
Whenever I try to fetch a product using an id it returns null, at the same time if i try to fetch the list am getting all the products but with the primary key property having the value 0 for all the products. Probably the primary key is not getting stored and hence am not able to fetch individual product using id.
Also, in the model class I had tried defining the primary key and Json Property in separate lines like mentioned below.
public class Product : RealmObject
{
[PrimaryKey]
[JsonProperty(PropertyName = "productId")]
public int ProductId { get; set; }
[JsonProperty(PropertyName = "parentId")]
public int ParentId { get; set; }
[JsonProperty(PropertyName = "productType")]
public string ProductType { get; set; }
}
I am using Simple Membership and a UserProfile table that maintains UserId and UserName:
public partial class UserProfile
{
public UserProfile()
{
this.webpages_Roles = new List<webpages_Roles>();
}
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<webpages_Roles> webpages_Roles { get; set; }
}
With Entity Framework I am running the following which is inside my Context:
public partial class UowContext : DbContext
// code to set up DbSets here ...
public DbSet<Content> Contents { get; set; }
private void ApplyRules()
{
var r1 = new Random();
var r2 = new Random();
foreach (var entry in this.ChangeTracker.Entries()
.Where(
e => e.Entity is IAuditableTable &&
(e.State == EntityState.Added) ||
(e.State == EntityState.Modified)))
{
IAuditableTable e = (IAuditableTable)entry.Entity;
if (entry.State == EntityState.Added)
{
e.CreatedBy = // I want to put the integer value of UserId here
e.CreatedDate = DateTime.Now;
}
e.ModifiedBy = // I want to put the integer value of UserId here
e.ModifiedDate = DateTime.Now;
}
}
Here is the schema showing how user information is stored. Note that I store the integer UserId and not the UserName in the tables:
public abstract class AuditableTable : IAuditableTable
{
public virtual byte[] Version { get; set; }
public int CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public int ModifiedBy { get; set; }
public DateTime ModifiedDate { get; set; }
}
Here's an example of a controller action that I use:
public HttpResponseMessage PostContent(Content content)
{
try
{
_uow.Contents.Add(content);
_uow.Commit();
var response = Request.CreateResponse<Content>(HttpStatusCode.Created, content);
return response;
}
catch (DbUpdateException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.Conflict, ex);
}
}
I then have:
public class UowBase : IUow, IDisposable
{
public UowBase(IRepositoryProvider repositoryProvider)
{
CreateDbContext();
repositoryProvider.DbContext = DbContext;
RepositoryProvider = repositoryProvider;
}
public IRepository<Content> Contents { get { return GetStandardRepo<Content>(); } }
and:
public class GenericRepository<T> : IRepository<T> where T : class
{
public GenericRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("An instance of DbContext is required to use this repository", "context");
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
public virtual void Add(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
How can I determine the UserId from inside of my Context so I can populate the Id in my tables?
In Code you will have UserName with you through:
HttpContext.Current.User.Identity.Name
you can than query UserProfile table against that Name and get the UserId from there and than assign it to ModifiedBy attribute.
Make sure that you query UserProfile table outside the foreach loop :)
For example I have two entities
Class A
{
public Guid Id {get;set;}
public Guid BId {get;set;}
public B InstanceB {get;set;}
}
Class B
{
public Guid Id {get;set}
}
B is related to A, on my silver light application I am creating a new instance of A, and also a new instance of B. The new instance of B does not exist yet. But I need the instance of B on my service.
Can I do this without Entity or Association with Ria Service?
Edit:
My Class A :
public partial class lSync{
// Metadata classes are not meant to be instantiated.
private lSync() {
}
public string ConflictMessage { get; set; }
public DateTime DateInserted { get; set; }
public Guid vValuesId { get; set; }
public Guid ID { get; set; }
public bool IsConflict { get; set; }
public bool IsReadyToSync { get; set; }
public Guid SyncSet { get; set; }
public vValues vValues { get; set; }
}
My Ria Service:
[Invoke]
public lSync[] SynchvValuesFromClient(lSync[] syncs) {
bool noConflict = true;
foreach (lSync sync in syncs) {
var servervValue = GetvValuesByID(sync.vValuesId).FirstOrDefault();
var queuevValues = sync.vValues; //sync.vValues here is null, but my sync.vValuesId is not
if (servervValue== null) {
InsertvValues(queueValue);
}
else {
if (servervValue.IsServerConflict(queueValue)) {
sync.IsConflict = true;
sync.ConflictMessage = "Conflict";
noConflict = false;
break;
}
if (!servervValue.AreValuesEqual(queueValue)) {
UpdatevValues(queueValue);
}
}
}
if (noConflict) {
this.ObjectContext.SaveChanges();
}
return syncs;
}
public IQueryable<vValues> GetvValuesByID(Guid ID) {
return ObjectContext.vValues.Where(t => t.ID == ID);
}
public void InsertvValues(vValues model) {
model.ServerDate = DateTime.UtcNow;
if ((model.EntityState != EntityState.Detached)) {
this.ObjectContext.ObjectStateManager.ChangeObjectState(model, EntityState.Added);
}
else {
this.ObjectContext.vValues.AddObject(model);
}
}
public void UpdatevValues(vValuesmodel) {
model.ServerDate = DateTime.UtcNow;
this.ObjectContext.vValues.AttachAsModified(model, this.ChangeSet.GetOriginal(model));
}
:(
Edit
The order is wrong of your method :)
Make an instance of the service before creating instances of the Entities.
It should be:
public void SyncToServer() {
ContextService service = new ContextService();
var instanceA = new A();
instanceA.InstanceB = new B();
service.SubmitChanges(); //service.SaveChanges() for LinqToEntities
}
Are you reloading after a submit because only adding the [Include] attribute in the DomainService MetaData won't work. You need to do this in the DomainService for LinqToSql
public A GetA()
{
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<A>(a => a.InstanceB);
this.DataContext.LoadOptions = dlo;
return this.DataContext.APlural.FirstOrDefault( ); //don't know the plural of A.
}
LinqToEntities:
public A GetA()
{
return this.MyEntitiesContext.APlural.Include( "instanceB" ).FirstOrDefault( ); //don't know the plural of A.
}
var a = new A(){
B = new B(); //or (B)selectedItem
}
now a.Id and a.BId is 0 until you SaveChanged and return saved A