entity framework join 2 tables without modifying domain models - sql

hey new to entity framework and i have these 2 models
SynchronizationProfile
public class SynchronizationProfileDBEntity
{
public string SyncProfileId { get; set; }
public string Code { get; set; }
public SynchronizationType SyncType { get; set; }
public string Schedule { get; set; }
public string UserName { get; set; }
}
SynchronizationLog
public class SynchronizationLogDBEntity
{
public string SyncLogId { get; set; }
public string SyncProfileId { get; set; }
public DateTime Ts { get; set; }
public SyncLogStatus LogStatus { get; set; }
}
there are no foreign keys on these because my team doesnt do it and get the results directly with LINQ
i want to get everything from SynchronizationLog(table) + Code(which is the name for everySyncProfileId) property from SynchronizationProfile
So i tried left join but for some reason dont get me the results.
var profiles = (from item in context.SynchronizationLogs
join item2 in context.SynchronizationProfiles
on item.SyncProfileId equals item2.SyncProfileId into gj
from subitem in gj.DefaultIfEmpty()
select new
{
SyncLogId = item.SyncLogId,
SyncProfileId = item.SyncProfileId,
Ts = item.Ts,
LogStatus = item.LogStatus
Code = item2.Code
}
Is my approach wrong?

Related

Getting error when adding new object with HTTP POST in .NETCore

I am new to .NetCore and Blazor. I am trying to do a POST of an new Anime, but I am allways getteing the error "The Genre field is required." I have added the genreId to the JSON Object but still the same error -> Screenshot of the error
It's one to many relation, where one animal can have only one genre but one genre can have many enemies.
I don't know if it's useful but here are screenshots of my two tables in the DB -> Anime table and the Genre tab
Here are my to Models:
Anime model
public class Anime
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string CoverImage { get; set; } = string.Empty;
public string Author { get; set; } = string.Empty;
public Genre Genre { get; set; }
public string Studio { get; set; } = string.Empty;
public DateTime? ReleaseDate { get; set; }
public DateTime? EndDate { get; set; }
}
Genre model
public class Genre
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[JsonIgnore]
public List<Anime> Animes { get; set; }
}
AnimeService where I am adding the new anime to the DB
public async Task<ServiceResponse<List<Anime>>> AddAnime(Anime NewAnime)
{
ServiceResponse<List<Anime>> serviceResponse = new ServiceResponse<List<Anime>>();
_dataContext.Animes.Add(NewAnime);
await _dataContext.SaveChangesAsync();
var animes = await _dataContext.Animes
.Include(a => a.Genre)
.ToListAsync();
if (animes == null)
{
serviceResponse.Success = false;
serviceResponse.Message = "Animes could be found!";
}
serviceResponse.Data = animes;
return serviceResponse;
}
AnimeController
[HttpPost]
[Route("AddAnime")]
public async Task<ActionResult<ServiceResponse<List<Anime>>>> AddAnime(Anime NewAnime)
{
return Ok(await _animeService.AddAnime(NewAnime));
}
As we discussed on Discord:
You're using .NET 6 with nullables enabled.
As an Anime can exist before it has Genre assigned I would configure the tables like this:
public class Anime
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string CoverImage { get; set; } = string.Empty;
public string Author { get; set; } = string.Empty;
public int? GenreId { get; set; }
[ForeignKey(nameof(GenreId))]
public Genre? Genre { get; set; }
public string Studio { get; set; } = string.Empty;
public DateTime? ReleaseDate { get; set; }
public DateTime? EndDate { get; set; }
}
public class Genre
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[JsonIgnore]
[InverseProperty(nameof(Anime.Genre))]
public List<Anime> Animes { get; set; }
}
It seems that your Anime instance don't habe a Genre object but it is requiered in your db context
You have to add navigation property GenreId as nullable if you think that Genre is optional
public class Anime
{
public int Id { get; set; }
... another properties
public int? GenreId { get; set; }
public virtual Genre Genre { get; set; }
}
after this you will have to make a new database migration

LINQ Query Syntax (getting error)

I am trying to understand the syntax of a LINQ query. I tried creating one to select all rows from my TRACK_INFO table where the column collegeOf was equal to a variable. My database name is KuPlan. Below is the query I tried to create and my TRACK_INFO model. The error i get is: "could not find an implementation of the query pattern for source type KU_PLAN_DEV.Models.TRACK_INFO. 'Where' not found."
controller:
var query = from degreeName in TRACK_INFO
where degreeName == trackButton
select degreeName;
model:
namespace KU_PLAN_DEV.Models
{
using System;
using System.Collections.Generic;
public partial class TRACK_INFO
{
public TRACK_INFO()
{
this.CORE_HEAD = new HashSet<CORE_HEAD>();
this.GEN_ED_HEAD = new HashSet<GEN_ED_HEAD>();
this.GEN_ED_NOTE = new HashSet<GEN_ED_NOTE>();
this.GRAD_CLEAR_HEAD = new HashSet<GRAD_CLEAR_HEAD>();
this.MAJOR_NOTE = new HashSet<MAJOR_NOTE>();
}
public string progNum { get; set; }
public string versionNum { get; set; }
public string degreeName { get; set; }
public string collegeOf { get; set; }
public string effectiveDateTerm { get; set; }
public Nullable<decimal> effectiveDateYear { get; set; }
public string trackDegreeType { get; set; }
public virtual ICollection<CORE_HEAD> CORE_HEAD { get; set; }
public virtual ICollection<GEN_ED_HEAD> GEN_ED_HEAD { get; set; }
public virtual ICollection<GEN_ED_NOTE> GEN_ED_NOTE { get; set; }
public virtual ICollection<GRAD_CLEAR_HEAD> GRAD_CLEAR_HEAD { get; set; }
public virtual GRAD_CLEAR_SIG_DATE GRAD_CLEAR_SIG_DATE { get; set; }
public virtual ICollection<MAJOR_NOTE> MAJOR_NOTE { get; set; }
}
}
TRACK_INFO is a class name, not an IEnumerable<TRACK_INFO>. I think you meant to get a property off of your context:
from degreeName in context.TRACK_INFO
...

Entity framework The column 'x' was specified multiple times for 'Filter1'

Developing Asp .Net MVC web application. Using Entity framework 6.1.1 and Visual Studio 2013.
Got this Linq:
Db.Distrule_contents.Where(x => x.distrule_id == DistruleId && x.Content.season_id.HasValue && x.Content.season.series_id == SeriesId).Select(x => x.Content).ToList();
and associated with DB tables classes:
[Table("distrule_content")]
public class Distrule_content
{
[Key,Column(Order=0)]
public int distrule_id { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("Content")]
public string IDEC { get; set; }
public int status_id { get; set; }
public virtual Distrule Distrule { get; set; }
public virtual Content Content { get; set; }
public virtual Status Status { get; set; }
}
[Table("distrule")]
public class Distrule: CommonEntity
{
public string distrule_name { get; set; }
public DateTime? begin_date { get; set; }
public DateTime end_date { get; set; }
public int status_id { get; set; }
public int? minutes_to_tx { get; set; }
public string period_type { get; set; }
public bool? autoactivate_content { get; set; }
public virtual ICollection<Distrule_area> DistruleAreas { get; set; }
public virtual ICollection<Distrule_content> DistruleContent { get; set; }
public virtual ICollection<Distrule_georegion> DistruleGeoregion { get; set; }
public virtual Status status { get; set; }
}
[Table("content")]
public class Content
{
[Key]
public string IDEC { get; set; }
public DateTime? date_inserted { get; set; }
public DateTime? min_tx_date { get; set; }
public long? season_id { get; set; }
public int? episode_number { get; set; }
public string content_rus_name { get; set; }
public virtual Season season { get; set; }
}
[Table("status")]
public class Status: CommonEntity
{
public string status_name { get; set; }
}
As a Result receave this SQL Query:
SELECT
[Filter1].[distrule_id1] AS [distrule_id],
[Filter1].[IDEC1] AS [IDEC],
[Filter1].[date_inserted1] AS [date_inserted],
[Filter1].[min_tx_date1] AS [min_tx_date],
[Filter1].[season_id1] AS [season_id],
[Filter1].[episode_number1] AS [episode_number],
[Filter1].[content_rus_name1] AS [content_rus_name],
[Filter1].[season_id2] AS [season_id1]
FROM ( SELECT [Extent1].[distrule_id] AS [distrule_id1], [Extent1].[Distrule_Id] AS [distrule_id1], [Extent2].[IDEC] AS [IDEC1], [Extent2].[date_inserted] AS [date_inserted1], [Extent2].[min_tx_date] AS [min_tx_date1], [Extent2].[season_id] AS [season_id1], [Extent2].[episode_number] AS [episode_number1], [Extent2].[content_rus_name] AS [content_rus_name1], [Extent2].[season_Id] AS [season_id1], [Extent3].[series_id] AS [series_id1], [Extent3].[Series_Id] AS [series_id1], [Extent4].[season_id] AS [season_id2], [Extent4].[season_Id] AS [season_id2]
FROM [dbo].[distrule_content] AS [Extent1]
INNER JOIN [dbo].[content] AS [Extent2] ON [Extent1].[IDEC] = [Extent2].[IDEC]
LEFT OUTER JOIN [dbo].[Season] AS [Extent3] ON [Extent2].[season_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[content] AS [Extent4] ON [Extent1].[IDEC] = [Extent4].[IDEC]
WHERE [Extent2].[season_id] IS NOT NULL
) AS [Filter1]
WHERE ([Filter1].[distrule_id1] = #p__linq__0) AND ([Filter1].[series_id1] = #p__linq__1)
And following error: The column 'distrule_id1' was specified multiple times for 'Filter1'.
What i am doing wrong?
update 2014-09-10
Solved after deep study EF navigation rules. Thx to chconger. Problem was in letting EF self realize where FK should be placed. So after adding everywhere ForeignKey attribute is worked fine.
Here how it looks now:
[Table("distrule_content")]
public class Distrule_content
{
[Key,Column(Order=0)]
public int distrule_id { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("Content")]
public string IDEC { get; set; }
public int status_id { get; set; }
[ForeignKey("distrule_id")]
public virtual Distrule Distrule { get; set; }
[ForeignKey("IDEC")]
public virtual Content Content { get; set; }
[ForeignKey("status_id")]
public virtual Status Status { get; set; }
}
Couple of issues from what I can see.
1. You have a foreign key set above a mismatched string IDEC, instead
[Key, Column(Order = 1)]
[ForeignKey("Content")]
public virtual Content Content { get; set; }
2. You are missing a constructor with HashSets for your class Distrule
public Distrule()
{
DistruleAreas = new HashSet<DistruleArea>();
DistruleContents = new HashSet<DistruleContent>();
DistruleGeoregions = new HashSet<DistruleGeregion>();
}

Ravendb TransformResults showing null values for properties populated with Load()

I have two documents Ticket and MenuItem i have created index with TransformResults but problem is i am getting null value for Loaded document in transform
public class Ticket
{
public int ID { get; set; }
public int ItemId { get; set; }
public string ItemName { get; set; }
public int Price { get; set; }
}
public class MenuItem
{
public int ID { get; set; }
public string ItemName { get; set; }
public string PriceCategory { get; set; }
}
i have created a index like
public class TicketItemGross : AbstractIndexCreationTask<Ticket, TicketItemGross.TicketItemDetails>
{
public class TicketItemDetails
{
public string ID { get; set; }
public string ItemId { get; set; }
public string ItemName { get; set; }
public int Price { get; set; }
public string PriceCategory { get; set; }
}
public TicketItemGross()
{
Map = docs => from doc in docs
select new
{
ID = doc.ID,
ItemId=doc.ItemId,
ItemName=doc.ItemName,
Price=doc.Price
};
TransformResults = (database, docs) => from m in docs
let d = database.Load<MenuItem>(m.ID)
select new
{
ID = m.ID,
ItemId = m.ItemId,
ItemName = m.ItemName,
Price = m.Price,
PriceCategory=d.PriceCategory
};
}
}
and the problem is that when i query data. I get null for PriceCategory but for all other fields i get correct value
here is query
IEnumerable<TicketItemGross.TicketItemDetails> list;
using (var session = store.OpenSession())
{
list = session.Query<TicketItemGross.TicketItemDetails, TicketItemGross>();
}
This is happening because you are using integer IDs. When you call database.Load in your transform, you'll need to manually convert it to a string ID.
database.Load<MenuItem>("MenuItems/" + m.ID)
This is one of several places where Raven gets confused if you use integer or guid IDs. If you use string ids, you won't have this problem.
Also, you might consider using a results transformer instead. They are easier than index transformers, which are now obsolete.

Accessing data in a ViewModel

I have the following entity framework code snippet which has a "Groups" table and a child "ApplicationsGroupsLK" table that contains an ApplicationID field that I need.
IEnumerable<Groups> Groups = DbContext.Groups.Include("ApplicationsGroupsLK").Where(p => p.GroupNumber > 0);
The child data comes back obviously in a collection.
I basically need to display the parent data along with the child ApplicationID field (many Applications to 1 Group).
In my MVC View, what should my ViewModel look like that would contain the parent and child data coming back that I need in order that I can properly bind it to a grid?
Second post:
Further, the following model was generated from Entity Framework:
public partial class Project
{
public Project()
{
this.TimeTrackings = new HashSet<TimeTracking>();
}
[DataMember]
public short ProjectID { get; set; }
[DataMember]
public short CustomerID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public short CategoryID { get; set; }
[DataMember]
public short PriorityID { get; set; }
[DataMember]
public short StatusID { get; set; }
[DataMember]
public Nullable<decimal> Quote { get; set; }
[DataMember]
public string Notes { get; set; }
[DataMember]
public System.DateTime CreatedDate { get; set; }
[DataMember]
public Nullable<System.DateTime> UpdatedDate { get; set; }
[DataMember]
public virtual Category Category { get; set; }
[DataMember]
public virtual Customer Customer { get; set; }
[DataMember]
public virtual Priority Priority { get; set; }
[DataMember]
public virtual Status Status { get; set; }
[DataMember]
public virtual ICollection<TimeTracking> TimeTrackings { get; set; }
}
You can see that TimeTrackings is the child table of Project. You can also see that CategoryID, CustomerID, PriorityID, and StatusID are foreign keys that the parent table has. In this case, I'm only interested in the CategoryID FK.
I haven't done this yet (not at my machine at home), but when I get the data into this model, what would actually be contained in the public virtual Category Category field? Since it's not a collection, what data is returned in this field after the query executes.
Third post:
Telerik asp.net for mvc syntax for DB call:
IEnumerable<Groups> GroupList = db.GetGroups();
return View(new GridModel<Groups>
{
Data = GroupList
});
Fourth post:
Trey, below is the code I modified for my purposes and was hoping you can check it over before I implement it. I think I undersand it and seems great...
public partial class Project
{
public Project()
{
this.TimeTrackings = new HashSet<TimeTracking>();
}
[DataMember]
public short ProjectID { get; set; }
[DataMember]
public short CustomerID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public short CategoryID { get; set; }
[DataMember]
public short PriorityID { get; set; }
[DataMember]
public short StatusID { get; set; }
[DataMember]
public Nullable<decimal> Quote { get; set; }
[DataMember]
public string Notes { get; set; }
[DataMember]
public System.DateTime CreatedDate { get; set; }
[DataMember]
public Nullable<System.DateTime> UpdatedDate { get; set; }
[DataMember]
public short ApplicationID { get; set; }
[DataMember]
public string ApplicationName { get; set; }
[DataMember]
public virtual Category Category { get; set; }
[DataMember]
public virtual Customer Customer { get; set; }
[DataMember]
public virtual Priority Priority { get; set; }
[DataMember]
public virtual Status Status { get; set; }
[DataMember]
public virtual ICollection<TimeTracking> TimeTrackings { get; set; }
public ProjectModel(Project project)
{
ProjectID = project.ProjectID;
CustomerID = project.CustomerID;
Name = project.Name;
Description = project.Description;
CategoryID = project.CategoryID;
PriorityID = project.PriorityID;
StatusID = project.StatusID;
Quote = project.Quote;
Notes = project.Notes;
CreatedDate = project.CreatedDate;
UpdatedDate = project.UpdatedDate;
ApplicationID = project.ApplicationsGroupsLK.ApplicationID;
ApplicationName = project.ApplicationsGroupsLK.ApplicationName;
}
// Neat Linq trick to convert database query results directly to Model
public static IList<ProjectModel> FlattenToThis(IList<Project> projects)
{
return projects.Select(project => new ProjectModel(project)).ToList();
}
}
Fifth post:
using (wmswebEntities DbContext = new wmswebEntities())
{
DbContext.Configuration.ProxyCreationEnabled = false;
DbContext.Database.Connection.Open();
IEnumerable<Projects> projects = DbContext.Projects.Where(p => p.GroupNumber > 0);
IList<ProjectModel> results = Project.FlattenToThis(projects);
return results
}
Sixth post
namespace CMSEFModel
{
using System;
using System.Collections.Generic;
public partial class GroupModel
{
public GroupModel()
{
this.ApplicationsGroupsLKs = new HashSet<ApplicationsGroupsLK>();
this.GroupApplicationConfigurationsLKs = new HashSet<GroupApplicationConfigurationsLK>();
this.UsersGroupsLKs = new HashSet<UsersGroupsLK>();
}
public int GroupNumber { get; set; }
public string GroupName { get; set; }
public int GroupRank { get; set; }
public bool ActiveFlag { get; set; }
public System.DateTime DateAdded { get; set; }
public string AddedBy { get; set; }
public System.DateTime LastUpdated { get; set; }
public string LastUpdatedBy { get; set; }
// Application - Lazy Loading population
public int ApplicationID { get; set; }
// UsersGroupsLK - Lazy Loading population
public int UserNumber { get; set; }
public string UserID { get; set; }
public virtual ICollection<ApplicationsGroupsLK> ApplicationsGroupsLKs { get; set; }
public virtual ICollection<GroupApplicationConfigurationsLK> GroupApplicationConfigurationsLKs { get; set; }
public virtual ICollection<UsersGroupsLK> UsersGroupsLKs { get; set; }
public GroupModel()
{}
public GroupModel(GroupModel group)
{
GroupNumber = group.GroupNumber;
GroupName = group.GroupName;
ActiveFlag = group.ActiveFlag;
DateAdded = group.DateAdded;
AddedBy = group.AddedBy;
LastUpdated = group.LastUpdated;
LastUpdatedBy = group.LastUpdatedBy;
UserNumber = group.UsersGroupsLKs.
}
// Neat Linq trick to convert database query results directly to Model
public static IList<GroupModel> FlattenToThis(IList<GroupModel> groups)
{
return groups.Select(group => new GroupModel(group)).ToList();
}
}
}
Seventh Post - this is the model I am having trouble with about the errors I previously posted. Trey, if you could help, I WOULD REALLY APPRECIATE IT.... I'm "dead in the water" unless I can get this part working.
namespace CMSEFModel
{
using System;
using System.Collections.Generic;
public partial class Group
{
public Group()
{
this.ApplicationsGroupsLKs = new HashSet<ApplicationsGroupsLK>();
this.GroupApplicationConfigurationsLKs = new HashSet<GroupApplicationConfigurationsLK>();
this.UsersGroupsLKs = new HashSet<UsersGroupsLK>();
}
public int GroupNumber { get; set; }
public string GroupName { get; set; }
public int GroupRank { get; set; }
public bool ActiveFlag { get; set; }
public System.DateTime DateAdded { get; set; }
public string AddedBy { get; set; }
public System.DateTime LastUpdated { get; set; }
public string LastUpdatedBy { get; set; }
// Application - Lazy Loading population
public int ApplicationID { get; set; }
// UsersGroupsLK - Lazy Loading population
public int UserNumber { get; set; }
public string UserID { get; set; }
public virtual ICollection<ApplicationsGroupsLK> ApplicationsGroupsLKs { get; set; }
public virtual ICollection<GroupApplicationConfigurationsLK> GroupApplicationConfigurationsLKs { get; set; }
public virtual ICollection<UsersGroupsLK> UsersGroupsLKs { get; set; }
public GroupModel(Group group)
{
GroupNumber = group.GroupNumber;
GroupName = group.GroupName;
ActiveFlag = group.ActiveFlag;
DateAdded = group.DateAdded;
AddedBy = group.AddedBy;
LastUpdated = group.LastUpdated;
LastUpdatedBy = group.LastUpdatedBy;
UserNumber = group.UsersGroupsLKs.
}
// Neat Linq trick to convert database query results directly to Model
public static IList<GroupModel> FlattenToThis(IList<Group> groups)
{
return groups.Select(group => new GroupModel(group)).ToList();
}
}
}
Eight post:
using (wmswebEntities DbContext = new wmswebEntities())
{
DbContext.Configuration.ProxyCreationEnabled = false;
DbContext.Configuration.LazyLoadingEnabled = true;
DbContext.Database.Connection.Open();
List<Groups> myGroups = new List<Groups>();
var myGroups = from p in DbContext.Groups
where p.ActiveFlag = true
select new
{
p.Groups.ApplicationName,
p.Groups.GroupName,
p.Groups.GroupRank,
p.Groups.ActiveFlag,
p.Groups.DateAdded,
p.Groups.AddedBy,
p.Groups.LastUpdated,
p.Groups.LastUpdatedBy,
p.Groups.ApplicationsGroupsLK.ApplicationID,
p.Groups.UsersGroupsLK.UserNumber
};
return myGroups;
}
This will take a slight tweak in thinking. The Grid will only accept a flat model. This type of question is asked often, here is a starter answer: Kendo UI Grid - How to Bind to Child Properties
If that does not help, post more of your code here and I can work through it with you.