Entity Framework: Ambiguous match found - c#

I am using Entity Framework 6.1 in asp.net webform project. When I try to add new object into projects, I am getting Ambiguous match found exception.
I am using database first approach. I do not any manipulation in created models. I have read some questions about that problem. General cause is same named properties and navigation in class. I did not found any same named property.
Can you tell me what i missed?
Thank you
Code:
projects m_NewProject = new projects();
decimal m_CompanyRef = MemberHelperC.getUser().CompanyRef;
DateTime m_EndDate = GeneralHelperC.getCompanyDateTime().AddDays(5);
DateTime m_StartDate = GeneralHelperC.getCompanyDateTime();
customers m_Customer = myEntity.customers.Where(xXx => xXx.CompanyRef == m_CompanyRef).FirstOrDefault();
m_NewProject.ProjectLeadRef = MemberHelperC.getUserID();
m_NewProject.ProjectName = m_ProjectName;
m_NewProject.ProjectStatus = Convert.ToByte(1);
m_NewProject.SourceLangRef = Convert.ToDecimal(comboSourceLang.SelectedValue);
m_NewProject.TargetLangRef = Convert.ToDecimal(comboTargetLang.SelectedValue);
m_NewProject.DomainRef = Convert.ToDecimal(1);
m_NewProject.ProjectYear = GeneralHelperC.getCompanyDateTime()/*DateTime.Now*/.Year;
m_NewProject.EndDate = m_EndDate;
m_NewProject.StartDate = m_StartDate;
m_NewProject.TaskStepNameRef = m_TaskStepNameID;
m_NewProject.CustomerRef = Convert.ToDecimal(m_Customer.RID);
Random m_Random = new Random();
m_NewProject.ProjectUniqueID = m_Random.Next(0, 99999999);
m_NewProject.ProjectTBX = m_Dictionary.RID;
myEntity.projects.Add(m_NewProject);//exception occur this method
myEntity.SaveChanges();
Object Class:
public partial class projects
{
public projects()
{
this.projectnotes = new HashSet<projectnotes>();
this.projectpriceoffers = new HashSet<projectpriceoffers>();
this.projectreferencedoc = new HashSet<projectreferencedoc>();
this.projects1 = new HashSet<projects>();
this.taskstepexceptions = new HashSet<taskstepexceptions>();
this.tbxrelation = new HashSet<tbxrelation>();
this.tmproject = new HashSet<tmproject>();
this.tmrelation = new HashSet<tmrelation>();
this.wizardprojecttasks = new HashSet<wizardprojecttasks>();
this.works = new HashSet<works>();
}
public decimal RID { get; set; }
public string ProjectName { get; set; }
public decimal ProjectStatus { get; set; }
public decimal ProjectLeadRef { get; set; }
public System.DateTime EndDate { get; set; }
public System.DateTime StartDate { get; set; }
public int ProjectYear { get; set; }
public int ProjectUniqueID { get; set; }
public Nullable<decimal> ParentProjectRef { get; set; }
public Nullable<decimal> TMXHeaderRef { get; set; }
public decimal SourceLangRef { get; set; }
public decimal TargetLangRef { get; set; }
public decimal DomainRef { get; set; }
public decimal TaskStepNameRef { get; set; }
public Nullable<decimal> ProjectTBX { get; set; }
public Nullable<decimal> CustomerRef { get; set; }
public virtual customers customers { get; set; }
public virtual domainname domainname { get; set; }
public virtual language language { get; set; }
public virtual language language1 { get; set; }
public virtual ICollection<projectnotes> projectnotes { get; set; }
public virtual ICollection<projectpriceoffers> projectpriceoffers { get; set; }
public virtual ICollection<projectreferencedoc> projectreferencedoc { get; set; }
public virtual ICollection<projects> projects1 { get; set; }
public virtual projects projects2 { get; set; }
public virtual projectstatus projectstatus1 { get; set; }
public virtual tasknames tasknames { get; set; }
public virtual tbxdictionary tbxdictionary { get; set; }
public virtual tmxheaderinterface tmxheaderinterface { get; set; }
public virtual users users { get; set; }
public virtual ICollection<taskstepexceptions> taskstepexceptions { get; set; }
public virtual ICollection<tbxrelation> tbxrelation { get; set; }
public virtual ICollection<tmproject> tmproject { get; set; }
public virtual ICollection<tmrelation> tmrelation { get; set; }
public virtual ICollection<wizardprojecttasks> wizardprojecttasks { get; set; }
public virtual ICollection<works> works { get; set; }
}
}

Are you sure there are no same named property somewhere with different casing? It compiles as case sensative, but executes as case insensitive, so even a few capital letters difference in a same name property could cause a Ambiguous match found exception.

I had the same problem:
I had a table named service linked to the table order.
Inside my partial class order, I was using a property called Service.
//Auto generated:
public virtual service service { get; set; }
//My custom property (Shortned, there was a big String.Format inside):
public String Service { get { return service.ds_name; }}
Case insensitive. :/
TL;DR: Property inside partial class with the same name, but with diffferent caps.

I solved my problem. There is a really ambiguous in my code. CustomerStatus really dublicated.
I think Entity Framework team should improve Ambiguous match found exception details. I have more than 90 tables and very hard to debugging...
Exception occure of these code:
public partial class customers
{
public enum CustomerStatusEnum : long
{
Closed = 3,
Open = 1,
Potential = 2
}
public CustomerStatusEnum CustomerStatus
{
get
{
return (CustomerStatusEnum)Status;
}
}
}

Related

I want to add 2 entities at once

I want to add 2 entities at once. When I want to add an offer, let the offer detail be added at the same time.
But let's add more than one detail to a quote.
I can't do this. I will be glad if you help.
public class Offer
{
public int Id { get; set; }
public int CompanyId { get; set; }
public int CompanyContactId { get; set; }
public int OfferNumber { get; set; }
public string Annotations { get; set; }
public string CommercialConditions { get; set; }
public string TimeInformation { get; set; }
public decimal ProfitRate { get; set; }
public DateTime Date { get; set; }
public DateTime ValidityDate { get; set; }
public Currency Currency { get; set; }
public Status Status { get; set; }
//Navigation Property
public virtual Company Company { get; set; }
public virtual CompanyContact CompanyContact { get; set; }
public virtual List<OfferDetail> OfferDetail { get; set; }
public class OfferDetail
{
//public int Id { get; set; }
public int OfferId { get; set; }
public int RowNumber { get; set; }
public int Quantity { get; set; }
public string Description { get; set; }
public decimal UnitPrice { get; set; }
public decimal TotalPrice { get; set; }
public string Definition { get; set; }
public Boolean Optional { get; set; }
public decimal UnitProfit { get; set; }
public decimal UnitCost { get; set; }
//public Currency Currency { get; set; }
//Navigation Properties
public Offer Offer { get; set; }
When I add the offer table to the database, the offer details are also added. But let another detail be added to a quote.
public async Task<Result> AddOffer(OfferInfo offerInfo)
{
try
{
var vOffer = new Offer
{
Id = offerInfo.Id,
CompanyId = offerInfo.CompanyId,
CompanyContactId = offerInfo.CompanyContactId,
OfferNumber = offerInfo.OfferNumber,
Annotations = offerInfo.Annotations,
CommercialConditions = offerInfo.CommercialConditions,
TimeInformation = offerInfo.TimeInformation,
ProfitRate = offerInfo.ProfitRate,
Date = offerInfo.Date,
ValidityDate = offerInfo.ValidityDate,
}; _context.Offers.Add(vOffer);
await _context.SaveChangesAsync();
return Result.PrepareSuccess();
}
catch (Exception vEx)
{
return Result.PrepareFailure(vEx.Message);
}
}
I can add from the model I created here.
This way I want to add both. Thanks in advance.
If you assign list of OfferDetail to Offer details entities will automatically be added to adequate table.
It should be something like this:
var vOffer = new Offer
{
// set all your properties of offer here
OfferDetails = new []
{
new OfferDetail {/*init details here*/},
// you can add more of details objects here
}
}
Chicken and egg problem, but there is a solution if you define constructors in OfferDetail that require the Offer and then add themselves to the List<OfferDetail>.
public class Offer
{
public Offer()
{
OfferDetail = new List<OfferDetail>();
}
//Navigation Property
public List<OfferDetail> OfferDetail { get; }
}
public class OfferDetail
{
public OfferDetail(Offer offer)
{
Offer = offer;
offer.OfferDetail.Add(this);
}
public int OfferId { get => Offer.Id; }
//Navigation Properties
public Offer Offer { get; }
}

AutoMapper for Nested inside Nested with Entity Framework?

I am trying to AutoMapper to EF models which are nested inside nested.
For Example in below code categorySrc, languageSrc, abstractSrc..etc and categoryDest, languageDest, abstractDest ..etc classes are same.
Now I am trying to Map categorySrc to categoryDest, So I made like below, if throwing an error
Is something I am doing wrong here?
var categoryData = abstractContext.GetCategoryByCatId(catId);
Mapper.CreateMap<Models.categoryDest, categorySource>();
Mapper.CreateMap<languageDest, Models.languageSource>();
Mapper.CreateMap<#abstractDest, Models.#abstractSrc>();
Mapper.CreateMap<abstract_categoryDest, Models.abstract_categorySrc>();
Mapper.CreateMap<questionDest, Models.questionSrc>();
Mapper.CreateMap ... //For other objects
Mapper.CreateMap ...//For other objects
Mapper.AssertConfigurationIsValid(); //Error occurring here
var category = Mapper.Map<category,Models.category>(categoryData);
Classes:
public partial class categoryDest
{
public int category_id { get; set; }
public int language_id { get; set; }
public virtual languageDest language { get; set; }
}
public partial class languageDest
{
public language()
{
this.abstracts = new HashSet<#abstractDest>();
this.abstract_category = new HashSet<abstract_categoryDest>();
this.categories = new HashSet<categoryDest>();
this.questions = new HashSet<questionDest>();
}
public int language_id { get; set; }
public string language_name { get; set; }
public string language_locale_code { get; set; }
public virtual ICollection<#abstractDest> abstracts { get; set; }
public virtual ICollection<abstract_categoryDest> abstract_category { get; set; }
public virtual ICollection<categoryDest> categories { get; set; }
public virtual ICollection<questionDest> questions { get; set; }
}
public partial class #abstractDest
{
public #abstract()
{
this.abstract_category = new HashSet<abstract_categoryDest>();
this.abstract_fields = new HashSet<abstract_fieldsDest>();
this.abstract_image = new HashSet<abstract_imageDest>();
this.people = new HashSet<person>();
}
public int abstract_id { get; set; }
public int language_id { get; set; }
public string abstract_name { get; set; }
public virtual ICollection<abstract_categoryDest> abstract_category { get; set; }
public virtual ICollection<abstract_fieldsDest> abstract_fields { get; set; }
public virtual ICollection<abstract_imageDest> abstract_image { get; set; }
public virtual languageDest language { get; set; }
public virtual ICollection<personDest> people { get; set; }
}
How to do this complex mapping?

Entity Framework navigation property

I'm trying to use EF to get data from my database. I have a table Interventions that has a Client associated with it like this:
public partial class Client
{
public Client()
{
this.Interventions = new List<Intervention>();
}
public int client_id { get; set; }
public string full_name { get; set; }
public string cgroup { get; set; }
public string nation { get; set; }
public virtual ICollection<Intervention> Interventions { get; set; }
}
public partial class Intervention
{
public int intervention_id { get; set; }
public int technician_id { get; set; }
public int client_id { get; set; }
public string type { get; set; }
public int done { get; set; }
public int year { get; set; }
public int month { get; set; }
public int week { get; set; }
public Nullable<int> avg_response_time { get; set; }
public int number_of_equip { get; set; }
public virtual Client Client { get; set; }
public virtual Technician Technician { get; set; }
}
I can get a list of interventions by doing this:
public object Any(GetInterventions request)
{
List<Intervention> dbItems;
using (var context = new operationsContext())
{
context.Configuration.LazyLoadingEnabled = false;
dbItems = context.Interventions.ToList();
return new GetInterventionsResponse{
interventions = dbItems
};
}
}
Although, when I try to retrieve the client associated with each intervention
dbItems = context.Interventions.Include("Client").ToList();
by including a Client navigation property I get a Visual Studio a stackOverflowException.
Am I doing anything wrong using EF or is just a question of general bad programming?
thanks in advance
The problem was solved by introducing decorations of [DataContract] and [DataMember] on the classes and fields that I wanted to serialize on the JSON response. Just like the example below:
using System.Runtime.Serialization;
namespace OperationsAPI.Models
{
[DataContract]
public partial class Intervention
{
public int intervention_id { get; set; }
public int technician_id { get; set; }
public int client_id { get; set; }
public string type { get; set; }
public int done { get; set; }
public int year { get; set; }
[DataMember]
public int month { get; set; }
[DataMember]
public int week { get; set; }
[DataMember]
public Nullable<int> avg_response_time { get; set; }
public int number_of_equip { get; set; }
[DataMember]
public virtual Client Client { get; set; }
public virtual Technician Technician { get; set; }
}
}

ASP.NET MVC /Entity Framework Error - Invalid column name 'Environment_Id'

I'm new to ASP.NET MVC and EF hopefully this is not a silly question
When i pass model to view i'm getting this error - Exception Details: System.Data.SqlClient.SqlException: Invalid column name 'Environment_Id'.
Model nor database table has a property by that name. Could any guide me on this?.
**Here is the Version Model Class**
public partial class Version
{
public Version()
{
this.ProfileVersions = new List<ProfileVersion>();
this.ServerInfoes = new List<ServerInfo>();
}
public int Id { get; set; }
public string Number { get; set; }
public string Tag { get; set; }
public string Owner { get; set; }
public string Approver { get; set; }
public string Description { get; set; }
public virtual ICollection<ProfileVersion> ProfileVersions { get; set; }
public virtual ICollection<ServerInfo> ServerInfoes { get; set; }
}
**Profile Version Class**
public partial class ProfileVersion
{
public ProfileVersion()
{
this.PlatformConfigurations = new List<PlatformConfiguration>();
}
public int Id { get; set; }
public int ProfileId { get; set; }
public int EnvironmentId { get; set; }
public int VersionId { get; set; }
public Nullable<bool> Locked { get; set; }
public string LockedBy { get; set; }
public string Comments { get; set; }
public Nullable<int> Active { get; set; }
public virtual Environment Environment { get; set; }
public virtual ICollection<PlatformConfiguration> PlatformConfigurations { get;
set; }
public virtual PlatformProfile PlatformProfile { get; set; }
public virtual Version Version { get; set; }
}
**ServerInfo**
public partial class ServerInfo
{
public ServerInfo()
{
this.PlatformConfigurations = new List<PlatformConfiguration>();
}
public int Id { get; set; }
public string ServerName { get; set; }
public int ProfileId { get; set; }
public int VersionId { get; set; }
public int EnvironmentId { get; set; }
public string ServerType { get; set; }
public Nullable<short> Active { get; set; }
public string Domain { get; set; }
public string Location { get; set; }
public string IP { get; set; }
public string Subnet { get; set; }
public string Gateway { get; set; }
public Nullable<int> VLan { get; set; }
public string DNS { get; set; }
public string OS { get; set; }
public string OSVersion { get; set; }
public string Func { get; set; }
public Nullable<short> IISInstalled { get; set; }
public string ADDomainController { get; set; }
public string ADOrganizationalUnit { get; set; }
public string ADGroups { get; set; }
public string LastError { get; set; }
public Nullable<System.DateTime> LastUpdate { get; set; }
public virtual Environment Environment { get; set; }
public virtual ICollection<PlatformConfiguration> PlatformConfigurations { get;
set; }
public virtual PlatformProfile PlatformProfile { get; set; }
public virtual Version Version { get; set; }
public virtual VMConfiguration VMConfiguration { get; set; }
}
**Controller Code-**
public ViewResult Index(string id )
{
var profileVerList = from ver in _context.Versions
where !(from pfv in _context.ProfileVersions
select pfv.VersionId).Contains(ver.Id)
select ver;
var bigView = new BigViewModel
{
VersionModel = profileVerList.ToList(),
};
return View(model: bigView);
}
**In the View where the exception is thrown**
#Html.DropDownList(
"SelectedVersionID",
new SelectList(
Model.VersionModel.Select(x => new { Value = x.Id, Text = x.Number}),
"Value",
"Text"
)
)
In your ProfileVersion and ServerInfo entities you have an Environment navigation property. By default, Entity Framework will try to create a database column called [Property Name]_[Referenced class PK]. In your scenario, that's Environment_Id. The problem, right now, is that you have not done a migration to have this database column created.
If I had to imagine what happened here, I'd say you first created the classes with EnvironmentId properties, migrated, then later decided to add the navigation properties, Environment to each, expecting EF to associate that with your existing EnvironmentId properties. That's where you went wrong. As I said above, EF convention is to look for a database column named Environment_Id, so if you want EF to use EnvironmentId instead, you just need to tell it so with the ForeignKey data annotation:
[ForeignKey("Environment")]
public int EnvironmentId { get; set; }
In My Case I have added My Primary Key Relationship to Same Key .. SO I have simply remove..
I realize this question is 3 years old now, but I saw a different reason for the error - both in the original question and in my own code that was pretty similar. And, in my case, I had the same error as stated above.
I had a "MY_ACTIONS" table with an ID and Name pair that I wanted to be added to a dropdown. Here's the model:
namespace TestSite.Models
{
public class MY_ACTIONS
{
//[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public MY_ACTIONS()
{
this.o_actions = new HashSet<MY_ACTIONS>();
}
[Key]
public int action_id { get; set; }
[StringLength(100)]
public string action_name { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<MY_ACTIONS> o_actions { get; set; }
}
}
And to get an action to display on the dropdown it had an ID set in an int field called LASTACTION in my main table. In that model I had declared the ForeignKey relationship:
namespace TestSite.Models
{
[Table("MAIN_TABLE")]
public partial class MAIN_TABLE
{
[Key]
public int MAIN_TABLE_ID { get; set; }
public int LASTACTION { get; set; } // this would carry a number matching action_id
[ForeignKey("LASTACTION")]
public virtual MY_ACTIONS MY_ACTIONS { get; set; }
}
}
I had the error Invalid column name 'MY_ACTIONS_action_id' when loading this dropdown in my view:
#Html.DropDownList("lastaction", null, htmlAttributes: new { #class = "form-control" })
...for which I was using this ViewBag in my Controller function:
Model1 db = new Model1(); // database context
MAIN_TABLE o_main = new MAIN_TABLE();
o_main.lastaction = 2;
ViewBag.lastaction = new SelectList(db.MY_ACTIONS, "action_id", "action_name", o_main.lastaction);
If I did not have my FK relationship declared:
[ForeignKey("LASTACTION")]
public virtual MY_ACTIONS MY_ACTIONS { get; set; }
I probably also would've had the same issue. Having the representation of a virtual instance requires linking it with some physical property. This is similar to how this:
public virtual Environment Environment { get; set; }
Should be:
[ForeignKey("EnvironmentId")]
public virtual Environment Environment { get; set; }
in the ProfileVersion class, in the question, above, assuming that EnvironmentId is the Primary Key in a table called Environment (that model is not shown above).
For me, though, I already had that and I was still getting the error, so doing that still might not solve everything.
Turns out all I had to do was get rid of that ICollection<MY_ACTIONS> o_actions in the MY_ACTIONS model and the this.o_actions = new HashSet<MY_ACTIONS>(); line and it all went through fine.
There are many such lists and ICollections in play in the question above, so I would wager something is wrong with having them, as well. Start with just a plain model that represents the fields, then add in your virtual objects that represent tables linked to with foreign keys. Then you make sure your dropdown loads. Only after that should you start adding in your ICollections, HashSets, Lists<T> and other such amenities that are not actually physically part of the database - this can throw off Entity Framework into thinking it needs to do something with them that it doesn't need to do.

Solution for IEnumerable.Contains() in entity framework linq queries

I am been using entity framework for my application. Unfortunately I can't make expressions like this one in entity framework:
List<MyUser> users = (from user in database.MyUsers
join app in database.MyApplications
on user.ApplicationId equals app.Id
where app.Name == this._applicationName
&& user.MyRoles.Contains(existingRole)
select user).ToList();
Any other approaches to this one. I don't want to change my database or my models. In my case the relationship between MyUser and MyRole is many to many with a glue table.
This is how the MyUser class is declared:
public partial class MyUser
{
public MyUser()
{
this.MyApiTokens = new HashSet<MyApiToken>();
this.MyLandingPages = new HashSet<MyLandingPage>();
this.MyPresentations = new HashSet<MyPresentation>();
this.MySlides = new HashSet<MySlide>();
this.MyUserSettings = new HashSet<MyUserSetting>();
this.MyRoles = new HashSet<MyRole>();
}
public System.Guid Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string EmailAddress { get; set; }
public int ApplicationId { get; set; }
public System.DateTime CreateDate { get; set; }
public System.DateTime LastActivityDate { get; set; }
public System.DateTime LastLockoutDate { get; set; }
public System.DateTime LastLoginDate { get; set; }
public System.DateTime LastPasswordChangedDate { get; set; }
public string PasswordQuestion { get; set; }
public string PasswordAnswer { get; set; }
public string Comment { get; set; }
public bool IsLocked { get; set; }
public bool IsApproved { get; set; }
public virtual ICollection<MyApiToken> MyApiTokens { get; set; }
public virtual MyApplication MyApplication { get; set; }
public virtual ICollection<MyLandingPage> MyLandingPages { get; set; }
public virtual ICollection<MyPresentation> MyPresentations { get; set; }
public virtual ICollection<MySlide> MySlides { get; set; }
public virtual ICollection<MyUserSetting> MyUserSettings { get; set; }
public virtual ICollection<MyRole> MyRoles { get; set; }
}
Assuming MyRoles is an association property in the entity model (i.e. maps to a table), you may want to make the matching explicit on the primary key of the role object. For example:
user.MyRoles.Any(r => r.RoleId == existingRole.RoleId)
There isn't enough information in your question to give an exact answer, though.

Categories