Which attributes should be used for right assotiation - c#

I'm using entity framework and have some classes
public class Lot
{
public int LotId { get; set; }
public string Description { get; set; }
public virtual Product Product { get; set; }
public virtual ApplicationUser Owner { get; set; }
public virtual ApplicationUser CurrentCustomer { get; set; }
public virtual ICollection<ApplicationUser> AllCustomers { get; set; }
public virtual AuctionDates AuctionDates { get; set; }
public virtual AuctionPrices AuctionPrices { get; set; }
public virtual State State { get; set; }
public virtual ProductImages Images { get; set; }
}
and
public class ApplicationUser : IdentityUser
{
[Required]
public virtual UserInfo UserInfo { get; set; }
public virtual ICollection<Lot> SelledLots { get; set; }
public virtual ICollection<Lot> BuyedLots { get; set; }
public virtual ICollection<Lot> ParticipatedLots { get; set; }
}
And the question is how can I set configuration for mapped user who Sell Lot(ApplicationUser) in Owner(Lot), who buy lot(ApplicationUser) in current customer(Lot) and so on. Thanks a lot.

I've finally found the answer. In this situation data annotation InverseProperty should be used. https://www.safaribooksonline.com/library/view/programming-entity-framework/9781449317867/ch04s03.html
public class Lot
{
public int LotId { get; set; }
public string Description { get; set; }
public virtual Product Product { get; set; }
[InverseProperty("SelledLots")]
public virtual ApplicationUser Owner { get; set; }
[InverseProperty("BuyedLots")]
public virtual ApplicationUser CurrentCustomer { get; set; }
[InverseProperty("ParticipatedLots")]
public virtual ICollection<ApplicationUser> AllCustomers { get; set; }
public virtual AuctionDates AuctionDates { get; set; }
public virtual AuctionPrices AuctionPrices { get; set; }
public virtual State State { get; set; }
public virtual ProductImages Images { get; set; }
}

Related

EF6 Code First -relationship may cause cycles or multiple cascade paths

Introducing FOREIGN KEY constraint 'FK_dbo.Queries_dbo.Users_UserID' on table 'Queries' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
public partial class User
{
public User()
{
this.Alerts = new HashSet<Alert>();
this.DeviceTokens = new HashSet<DeviceToken>();
this.MobileNotifications = new HashSet<MobileNotification>();
this.Queries = new HashSet<Query>();
this.SendQueries = new HashSet<SendQuery>();
}
public int ID { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string SSOID { get; set; }
public Nullable<System.DateTime> LastLogin { get; set; }
public int LatestUpdatedRecord { get; set; }
public virtual ICollection<Alert> Alerts { get; set; }
public virtual ICollection<DeviceToken> DeviceTokens { get; set; }
public virtual ICollection<MobileNotification> MobileNotifications { get; set; }
public virtual ICollection<Query> Queries { get; set; }
public virtual ICollection<SendQuery> SendQueries { get; set; }
}
public partial class Query
{
public Query()
{
this.AlertEmails = new HashSet<AlertEmail>();
this.Alerts = new HashSet<Alert>();
this.QueryFacets = new HashSet<QueryFacet>();
}
public int ID { get; set; }
public int UserID { get; set; }
public string EntityType { get; set; }
public string Name { get; set; }
public string SearchTerm { get; set; }
public string OrderBy { get; set; }
public string QueryType { get; set; }
public string ReceiveUpdateTime { get; set; }
public Nullable<System.DateTime> NextSendTime { get; set; }
public bool IsActive { get; set; }
public string Token { get; set; }
public string AlertName { get; set; }
public bool Enabled { get; set; }
public bool GetNotifications { get; set; }
public string TimeFilterType { get; set; }
public string TimeFilterValue { get; set; }
public string RectangleFilter { get; set; }
public virtual ICollection<AlertEmail> AlertEmails { get; set; }
public virtual ICollection<Alert> Alerts { get; set; }
public virtual ICollection<QueryFacet> QueryFacets { get; set; }
public virtual User User { get; set; }
}
public partial class SearchAndAlertDbContext : DbContext
{
public virtual DbSet<AlertEmail> AlertEmails { get; set; }
public virtual DbSet<AlertingTime> AlertingTimes { get; set; }
public virtual DbSet<Alert> Alerts { get; set; }
public virtual DbSet<DeviceToken> DeviceTokens { get; set; }
public virtual DbSet<IgnoredSlide> IgnoredSlides { get; set; }
public virtual DbSet<Log> Logs { get; set; }
public virtual DbSet<MobileNotification> MobileNotifications { get; set; }
public virtual DbSet<Query> Queries { get; set; }
public virtual DbSet<QueryFacet> QueryFacets { get; set; }
public virtual DbSet<SendQuery> SendQueries { get; set; }
public virtual DbSet<StoredQuery> StoredQueries { get; set; }
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<BlockedUserForActivity> BlockedUserForActivities { get; set; }
public virtual DbSet<UserActivity> UserActivities { get; set; }
public virtual DbSet<UserActivityIgnoreList> UserActivityIgnoreLists { get; set; }
public virtual DbSet<UserActivityMonitor> UserActivityMonitors { get; set; }
public virtual DbSet<UserActivitySpecificSetting> UserActivitySpecificSettings { get; set; }
public virtual DbSet<WarnedUserForActivity> WarnedUserForActivities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().
HasMany(p => p.Queries).
WithRequired(a => a.User).
HasForeignKey(a => a.UserID).WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
}
Tell EF not to cascade the query delete.
modelBuilder.Entity<Query>()
.HasRequired(q => q.User)
.WithMany(s => s.Queries)
.HasForeignKey(s => s.UserId)
.WillCascadeOnDelete(false);
Or turn off the convention:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

Entity Framework Unable to determine principal end of relationship. Multiple added entities may have same primary key

I'm having some issues with EF.
Migrations go fine, but when I try to run update-database I get the error :
Unable to determine the principal end of the 'LeagueInsight.Models.Image_Passive' relationship. Multiple added entities may have the same primary key.
Here are my models and config:
Passive.cs
public class Passive
{
public long Id { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public string SanitizedDescription { get; set; }
// Navigation
public virtual Image Image { get; set; }
public virtual Champion Champion { get; set; }
}
Image.cs
public class Image
{
public long Id { get; set; }
public string Full { get; set; }
public string Group { get; set; }
public int H { get; set; }
public string Sprite { get; set; }
public int W { get; set; }
public int X { get; set; }
public int Y { get; set; }
// Navigation
public virtual Champion Champion { get; set; }
public virtual ChampionSpell ChampionSpell { get; set; }
public virtual Passive Passive { get; set; }
}
DBContext Configuration Partial:
modelBuilder.Entity<Passive>()
.HasRequired(p => p.Champion)
.WithRequiredPrincipal(c => c.Passive);
modelBuilder.Entity<Info>()
.HasRequired(i => i.Champion)
.WithRequiredPrincipal(c => c.Info);
modelBuilder.Entity<Image>()
.HasOptional(i => i.Champion)
.WithRequired(c => c.Image);
modelBuilder.Entity<Image>()
.HasOptional(i => i.Passive)
.WithRequired(p => p.Image);
base.OnModelCreating(modelBuilder);
It is just supposed to be a 1-1 relationship between the two, an I can't figure out why there would be multiple entities with the same Id here.
Edit: I was asked for the champion class:
public class Champion
{
public int Id { get; set; }
public string Blurb { get; set; }
public string Key { get; set; }
public string Lore { get; set; }
public string Name { get; set; }
public string Partype { get; set; }
public string Title { get; set; }
// Navigation
[InverseProperty("Ally")]
public virtual ICollection<Tip> Allytips { get; set; }
[InverseProperty("Enemy")]
public virtual ICollection<Tip> Enemytips { get; set; }
public virtual Image Image { get; set; }
public virtual Info Info { get; set; }
public virtual Passive Passive { get; set; }
public virtual ICollection<Recommended> Recommended { get; set; }
public virtual ICollection<Skin> Skins { get; set; }
public virtual Stats Stats { get; set; }
public virtual ICollection<ChampionSpell> Spells { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}

Linq where with nested .Any() in string variable

These are my entities:
public class Subscription : BaseItem
{
public virtual DateTime DateStart { get; set; }
public virtual DateTime? DateEnd { get; set; }
public virtual int Status { get; set; }
public virtual Account Account { get; set; }
public virtual Theater Theater { get; set; }
public virtual Agent Agent { get; set; }
}
public class Account : BaseItem
{
public virtual string LegalName { get; set; }
public virtual string FirstName { get; set; }
public virtual string UrlName { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string ZipCode { get; set; }
public virtual string Country { get; set; }
public virtual string Tel { get; set; }
public virtual string Tel2 { get; set; }
public virtual string Fax { get; set; }
public virtual string Mobile { get; set; }
public virtual string Email { get; set; }
public virtual string Website { get; set; }
public virtual int DefaultVatRate { get; set; }
public virtual bool Bankrupt { get; set; }
public virtual string ExternalId { get; set; }
public virtual bool DoNotContact { get; set; }
public virtual bool NotInterested { get; set; }
public virtual Group Group { get; set; }
public virtual IList<Header> Headers { get; set; }
public virtual IList<Note> Notes { get; set; }
public virtual IList<Order> Orders { get; set; }
public virtual IList<Subscription> Subscriptions { get; set; }
}
public class Order : BaseItem
{
public virtual int Number { get; set; }
public virtual DateTime Date { get; set; }
public virtual string Description { get; set; }
public virtual double Amount { get; set; }
public virtual string Attachment { get; set; }
public virtual string AttachmentFilename { get; set; }
public virtual string AttachmentMimetype { get; set; }
public virtual bool? PaidToTheater { get; set; }
public virtual DateTime? DatePaidToTheater { get; set; }
public virtual bool? CashinByTheater { get; set; }
public virtual Account Account { get; set; }
public virtual Theater Theater { get; set; }
public virtual Agent Agent { get; set; }
public virtual IList<Invoice> Invoices { get; set; }
public virtual IList<OrdersAttachment> OrdersAttachments { get; set; }
public virtual IList<OrdersDueDate> OrdersDueDates { get; set; }
public virtual Header Header { get; set; }
}
public class Invoice : BaseItem
{
public virtual int Number { get; set; }
public virtual DateTime Date { get; set; }
public virtual double Amount { get; set; }
public virtual double VatRate { get; set; }
public virtual bool IsDisabled { get; set; }
public virtual bool IsSendMail { get; set; }
public virtual Order Order { get; set; }
public virtual IList<InvoicesDueDate> InvoicesDueDates { get; set; }
public virtual IList<InvoicesPayment> InvoicesPayments { get; set; }
}
I have a method in my program that build a "query" in a string variable.
private string GenerateQuery(FilterSubscription filterSubscription)
{
if (filterSubscription.FilterByOrder)
return "Account.Orders.Any()";
if (filterSubscription.FilterByInvoice)
return "Account.Orders.Any(Invoices.Any())"; //here is my problem
}
This is the call to the method
string query = GenerateQuery(filterSubscription)
var count = Session.Linq<Subscription>().Where(query).Count();
If I need to extract all accounts that have at least one Order is all OK.
But if I need to extract all accounts that have at least one Invoice I don't know how.
If I wrote
var count = Session.Linq<Subscription>().Where(s=>s.Account.Orders.Any(o=>o.Invoices.Any())).Count();
it works but if I use the string variable it doesn't.
It looks like you should return a delegate from GenerateQuery instead - something like:
private Expression<Func<Subscription, bool>> GenerateQuery(FilterSubscription filterSubscription)
{
if (filterSubscription.FilterByOrder)
return s => s.Account.Orders.Any();
if (filterSubscription.FilterByInvoice)
return s => s.Account.Orders.Any(o => o.Invoices.Any());
}
Then just update the query variable to be implicitly typed:
var query = GenerateQuery(filterSubscription);

How to write a many-to-many relationship in Fluent in MVC4 and Entity Code First

I'm trying to write a many-to-many relationship in the override of the onModelCreating method of my context in ASP.NET MVC4. I think I have my classes wrong because I'm getting errors in Intellisense that I don't understand. Here is my override:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Software>().
HasMany(i => i.LocationId).
WithMany(c => c.SoftwareId).
Map(mc =>
{
mc.MapLeftKey("SoftwareId");
mc.MapRightKey("LocationId");
mc.ToTable("SoftwareLocations");
});
}
Here is my Software class:
public class Software
{
public int Id { get; set; }
public virtual List<SoftwareType> SoftwareTypes { get; set; }
public virtual List<Location> Locations { get; set; }
public virtual List<SoftwarePublisher> Publishers { get; set; }
[Required]
[StringLength(128)]
public string Title { get; set; }
[Required]
[StringLength(10)]
public string Version { get; set; }
[Required]
[StringLength(128)]
public string SerialNumber { get; set; }
[Required]
[StringLength(3)]
public string Platform { get; set; }
[StringLength(1000)]
public string Notes { get; set; }
[Required]
[StringLength(15)]
public string PurchaseDate { get; set; }
public bool Suite { get; set; }
public string SubscriptionEndDate { get; set; }
//[Required]
//[StringLength(3)]
public int SeatCount { get; set; }
public virtual Location LocationId { get; set; }
}
Here is my Location class:
public class Location
{
public int Id { get; set; }
[Required]
[StringLength(20)]
public string LocationName { get; set; }
public virtual Software SoftwareId { get; set; }
}
How do I write my Fluent override so I can map them correctly?
Many-to-Many means that in both entities is Collections. So you should set HasMany(software=>software.Locations) and set WithMany(location=>location.Softwares) as in example:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Software>().
HasMany(i => i.Locations).
WithMany(c => c.Softwares).
Map(mc =>
{
mc.MapLeftKey("SoftwareId");
mc.MapRightKey("LocationId");
mc.ToTable("SoftwareLocations");
});
}
Here is my Software class:
public class Software
{
public int Id { get; set; }
public virtual List<SoftwareType> SoftwareTypes { get; set; }
public virtual ICollection <Location> Locations { get; set; }
public virtual List<SoftwarePublisher> Publishers { get; set; }
[Required]
[StringLength(128)]
public string Title { get; set; }
[Required]
[StringLength(10)]
public string Version { get; set; }
[Required]
[StringLength(128)]
public string SerialNumber { get; set; }
[Required]
[StringLength(3)]
public string Platform { get; set; }
[StringLength(1000)]
public string Notes { get; set; }
[Required]
[StringLength(15)]
public string PurchaseDate { get; set; }
public bool Suite { get; set; }
public string SubscriptionEndDate { get; set; }
//[Required]
//[StringLength(3)]
public int SeatCount { get; set; }
}
Here is my Location class:
public class Location
{
public int Id { get; set; }
[Required]
[StringLength(20)]
public string LocationName { get; set; }
public virtual ICollection<Software> Softwares { get; set; }
}

Code First Entity Framework disallows access to table

I am trying to use code first to generate a database for an asp.net mvc application. the OrderItem class does get generated as OrderItems table in the database but I end up without having any access to it. what can I do to allow the following for example: db.OrderItems.Find(id);
the model is as follows:
namespace CustomerOrders.Models{
public class Customer
{
public virtual int CustomerID { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string Company { get; set; }
public virtual string Email { get; set; }
public virtual string EmailCheck { get; set; }
}
public class Order
{
public virtual int OrderID { get; set; }
public virtual int CustomerID { get; set; }
public virtual DateTime OrderDate { get; set; }
public virtual double OrderTotal { get; set; }
public virtual double Tax { get; set; }
public virtual Customer Customer { get; set; }
public virtual List<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public virtual int OrderItemID { get; set; }
public virtual int OrderID { get; set; }
public virtual int ProductID { get; set; }
public virtual double PricePerItem { get; set; }
public virtual double Quantity { get; set; }
public virtual Product Product { get; set; }
public Order Order { get; set; }
}
public class Product
{
public virtual int ProductID { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual double Price { get; set; }
}
}
You probably haven't got the declaration in your dbContext so Open up the dbContext and add this:
public DbSet<OrderItem> OrderItems { get; set; }
you should end up with this:
public class CustomerOrdersDB : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
}

Categories