Say I have the following table definitions in SQL Server 2008:
CREATE TABLE Person
(PersonId INT IDENTITY NOT NULL PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
ManyMoreIrrelevantColumns VARCHAR(MAX) NOT NULL)
CREATE TABLE Model
(ModelId INT IDENTITY NOT NULL PRIMARY KEY,
ModelName VARCHAR(50) NOT NULL,
Description VARCHAR(200) NULL)
CREATE TABLE ModelScore
(ModelId INT NOT NULL REFERENCES Model (ModelId),
Score INT NOT NULL,
Definition VARCHAR(100) NULL,
PRIMARY KEY (ModelId, Score))
CREATE TABLE PersonModelScore
(PersonId INT NOT NULL REFERENCES Person (PersonId),
ModelId INT NOT NULL,
Score INT NOT NULL,
PRIMARY KEY (PersonId, ModelId),
FOREIGN KEY (ModelId, Score) REFERENCES ModelScore (ModelId, Score))
The idea here is that each Person may have only one ModelScore per Model, but each Person may have a score for any number of defined Models. As far as I can tell, this SQL should enforce these constraints naturally. The ModelScore has a particular «meaning,» which is contained in the Definition. Nothing earth-shattering there.
Now, I try translating this into Entity Framework using the designer. After updating the model from the database and doing some editing, I have a Person object, a Model object, and a ModelScore object. PersonModelScore, being a join table, is not an object but rather is included as an association with some other name (let’s say ModelScorePersonAssociation). The mapping details for the association are as follows:
- Association - Maps to PersonModelScore - ModelScore ModelId : Int32 <=> ModelId : int Score : Int32 <=> Score : int - Person PersonId : Int32 <=> PersonId : int
On the right-hand side, the ModelId and PersonId values have primary key symbols, but the Score value does not.
Upon compilation, I get:
Error 3002: Problem in Mapping Fragment starting at line 5190: Potential runtime violation of table PersonModelScore's keys (PersonModelScore.ModelId, PersonModelScore.PersonId): Columns (PersonModelScore.PersonId, PersonModelScore.ModelId) are mapped to EntitySet ModelScorePersonAssociation's properties (ModelScorePersonAssociation.Person.PersonId, ModelScorePersonAssociation.ModelScore.ModelId) on the conceptual side but they do not form the EntitySet's key properties (ModelScorePersonAssociation.ModelScore.ModelId, ModelScorePersonAssociation.ModelScore.Score, ModelScorePersonAssociation.Person.PersonId).
What have I done wrong in the designer or otherwise, and how can I fix the error?
Many thanks!
#entity-framework
#entity-framework
Вопрос:
У меня есть модель данных следующим образом:
У клиента есть продукты и способы оплаты. Каждому продукту может быть назначен любой или все способы оплаты Клиента, один из которых установлен по умолчанию.
Внешние ключи являются:
Customer.CustomerId => Product.CustomerId
Customer.CustomerId => PaymentMethod.CustomerId
Product.ProductId => ProductPaymentMethod.ProductId
PaymentMethod.PaymentMethodId => ProductPaymentMethod.PaymentMethodId
Я хочу настроить эту модель для целей презентации, чтобы у клиента была коллекция способов оплаты и коллекция продуктов. Продукты должны иметь коллекцию PRODUCTPAYMENTMETHOD, которые наследуются от PaymentMethod.
Я удалил связь между PaymentMethod и ProductPaymentMethod, добавил наследование от PaymentMethod к ProductPaymentMethod и удалил PaymentMethod ID из ProductPaymentMethod.
Теперь это моя модель:
Когда я сохраняю модель или создаю проект, я получаю 2 ошибки:
Ошибка 3002: Проблема с отображением фрагментов, начиная со строки 226: Потенциальное нарушение во время выполнения ключей table ProductPaymentMethod (ProductPaymentMethod.PRODUCTPAYMENTMETHOD id): Столбцы (ProductPaymentMethod.PRODUCTPAYMENTMETHOD id) сопоставляются со свойствами EntitySet PaymentMethods (PaymentMethods.PRODUCTPAYMENTMETHOD id) на концептуальной стороне, но они не формируют ключевые свойства EntitySet (PaymentMethods.Метод оплаты).
и
Ошибка 3003: Проблема с отображением фрагментов, начиная со строки 226: все ключевые свойства (PaymentMethods.PaymentMethod Id) из EntitySet Методы оплаты должны быть сопоставлены со всеми ключевыми свойствами (ProductPaymentMethod.PRODUCTPAYMENTMETHOD id) таблицы ProductPaymentMethod.
Что я делаю не так?
РЕДАКТИРОВАТЬ: После дальнейшего поиска в Google я нашел несколько решений, большинство из которых не совсем соответствуют этому сценарию. Большинство говорят о наследовании, требующем отношения 1-1, а не 1-много. Однако из-за отношения «Клиент-продукт 1-многие» модель требует соотношения «1-многие» между PaymentMethod и ProfilePaymentMethod. Невозможно ли сделать то, что я пытаюсь?
Комментарии:
1. Ссылки или краткое изложение ближайших решений, которые вы нашли, было бы неплохо.
Ответ №1:
Пока мой единственный ответ на это — иметь несколько созданных вручную классов POCO для представления и класс Mapper, чтобы превратить мой объект данных в объект представления
У меня есть консольное приложение, и что я пытаюсь сделать, так это то, что каждый раз, когда выполняется приложение, дата и время отправляются в таблицу в моей базе данных.
Структура таблицы выглядит так:
FTPRuns
ID int
Last Run datetime
Прост достаточно.
Я обновил model.edmx в своем приложении, чтобы отразить это новое изменение. Однако теперь я получаю следующую ошибку, и я не совсем уверен, что это значит.
Ошибка 3002: проблема при сопоставлении фрагменты, начинающиеся с линии 1330: Потенциальное нарушение времени выполнения таблицы FTPRuns (FTPRuns.ID): Столбцы (FTPRuns.ID) сопоставляются с Свойства EntitySet FTPRuns (FTPRuns.ID) на концептуальной стороне но они не образуют EntitySet ключевые свойства (FTPRuns.ID, FTPRuns.LastRun).
Вот фрагмент кода, который я использую для обновления базы данных:
using (ModelContainer ctn = new ModelContainer())
{
try
{
FTPRun ftp = new FTPRun
{
LastRun = DateTime.Now
};
ctn.FTPRuns.AddObject(ftp);
int changes = ctn.SaveChanges();
Console.WriteLine(changes.ToString() + " Changes saved");
Console.WriteLine("The LastRun Date Has Been Updated");
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.ToString());
}
}
Если кто-нибудь может мне помочь, я был бы очень благодарен:)
спасибо.
Ответ 1
Ваша модель сущности имеет комбинацию двух свойств FTPRuns.ID
и FTPRuns.LastRun
как ключ сущности, тогда как ваша таблица имеет только столбец FTPRuns.ID
в качестве первичного ключа. Поэтому в вашей модели вы указываете, что комбинация FTPRuns.ID
и FTPRuns.LastRun
должна быть уникальной, в то время как ваша база данных имеет более сильное требование, чтобы только FTPRuns.ID
было уникальным.
Просто исключите свойство FTPRuns.LastRun
из ключа сущности. Возможно, это произошло случайно или Entity Framework не смог получить информацию первичного ключа из базы данных и должен был вывести ключ сущности. Например, представления не имеют первичного ключа, а Entity Framework выведет ключ сущности как комбинацию всех столбцов, не подлежащих обнулению.
Ответ 2
это произошло со мной, когда я изменил ключевое поле в таблице (в базе данных) и обновил модель сущности.
Старый код все еще присутствовал в модели, поэтому я зашел в свойства объекта в файле .edmx и установил ключ в False. Это исправило это.
Ответ 3
Решение Daniel Brückner отлично работало для меня! Ниже, по сути, он инструктировал, но в графическом виде — что может помочь ленивым читателям:).
То, что вы хотите посмотреть, это то, что ваш ПК в модели i.e.
Мы видим, что у меня есть PK, называемый id
. Теперь, если я посмотрю на свою модель EF:
Я вижу только один указанный ключ, который является правильным. Для меня это было не так, все четыре столбца были ключами.
Если вы щелкните правой кнопкой мыши по столбцу (на диаграмме EF на VS), вы получите возможность отмечать/отключать Entity Key:
Убедитесь, что это соответствует вашей модели. В моем случае нужно отметить только id
, сохранить и построить проект.
Ответ 4
Я удалил таблицу из edmx (в edmx выберите таблицу, вызывающую проблему → щелкните правой кнопкой мыши → удалить)
а затем выполнить «обновленную модель из базы данных»
который зафиксировал это для меня
Ответ 5
Я удалил объект и класс из Обозревателя моделей и сделал обновление из базы данных, чтобы выбрать таблицу. Это разрешило проблему для меня.
Ответ 6
Я забыл установить первичный ключ при создании новой таблицы, поэтому я пошел в SQL Management Studio для этого. После этого я обновил файл model.edmx, чтобы отразить изменения и получил ошибку 3002.
То, что он сделал при обновлении модели, заключалось в том, чтобы установить все столбцы таблицы как «ключи сущностей». Поэтому, просматривая файл model.edmx, найдите соответствующую таблицу и щелкните правой кнопкой мыши по различным свойствам, чтобы убедиться, что выбран только первичный ключ «Entity key». Это решило мою проблему.
Ответ 7
Я удалил все таблицы из edmx, а затем «Обновить модель из базы данных».
Также проверьте наличие владельца базы данных.
Ответ 8
Проверьте основной ключ для таблицы, если он существует, тогда
1) Откройте файл .edmx, выберите все таблицы и Удалить из модели.
2) Обновить модель из БД и снова добавить все необходимые таблицы
Search code, repositories, users, issues, pull requests…
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
Сначала мы используем EF 3.5, базу данных. После того, как я обновил свой вид, я получил следующее сообщение об ошибке:
Ошибка 1 Ошибка 3002. Проблема во фрагменте сопоставления, начинающаяся со строки 866: Потенциальное нарушение во время выполнения ключей таблицы vPendingOrders
(vPendingOrders.AccountId, vPendingOrders.AccountName,
vPendingOrders.ApplicationModeTypeId,
vPendingOrflow.RidOHDFD.WD.Offer.OderSDDFD.WD.Offer_DFD.WD.Offer_DFD.WD.Offer_DFD.WD.Od_Ont_WD.Ont_WD.Ont_DBD.WD.Omper_PD.WD.WD.Omp_PD.WD.WD.Omp_PD.WD.Wader.Play.Play.Play.Play_PD.WD.Wader.PlayS_WD.WD.WD.Ch_P_WD.WD.Ch_P_WD.WD.Ch.). Ошибка 3002. vPendingOrders.InstanceId, vPendingOrders.OrgId, vPendingOrders.StartDate, vPendingOrders.TotalBudget): Столбцы (vPendingOrders.CampaignWorkflowId, vPendingOrders.InstanceId, vPendingOrders.OrgId, vPendingOrders.AccountId, vPendingOrders.AccountName, vPendingOrders.TotalBudget, vPendingOrders.StartDate, vPendingOrders.EndDate, vPendingOrders.HiddenInGeneralList, vPendingOrders.HiddenInOwnerList, vPendingOrders.ApplicationModeTypeId) отображаются в свойствах EntitySet vPendingOrders (в vPendingOrders.CampaignWorkflowId, vPendingOrders.InstanceId, vPendingOrders.OrgId, vPendingOrders.AccountId, vPendingOrders.AccountName, vPendingOrders.TotalB udget, vPendingOrders.StartDate, vPendingOrders.EndDate, vPendingOrders.HiddenInGeneralList, vPendingOrders.HiddenInOwnerList, vPendingOrders.ApplicationModeTypeId) на концептуальной стороне, но они не являются ключевыми свойствами EntitySet в (vPendingOrders.AccountId, vPendingOrders.AccountName, vPendingOrders.ApplicationModeTypeId, vPendingOrders. CampaignWorkflowId, vPendingOrders.EndDate, vPendingOrders.HiddenInGeneralList, vPendingOrders.HiddenInOwnerList, vPendingOrders.InstanceId, vPendingOrders.OrgId, vPendingOrders.SudotOders vPr.
Как вы видите, нет моих новых файлов FullName, Email и ContactId
Вид выглядит так:
CREATE VIEW [dbo].[vPendingOrders]
AS
SELECT TOP (100) PERCENT wf.CampaignWorkflow.CampaignWorkflowId, wf.CampaignWorkflow.InstanceId, dbo.vCampaigns.OrgId, wf.CampaignWorkflow.CampaignId,
dbo.vCampaigns.AccountId, wf.CampaignWorkflow.HasProposalReview, wf.CampaignWorkflow.HasMediaReview, wf.CampaignWorkflow.HasTraffickingEnabled,
dbo.vCampaigns.AccountName, wf.CampaignWorkflow.HasAuthorizedCreditCard, wf.CampaignWorkflow.HasAppliedForCredit, wf.CampaignWorkflow.HasDrops,
dbo.vCampaigns.TotalBudget, wf.CampaignWorkflow.StateMessage, dbo.vCampaigns.StartDate, dbo.vCampaigns.EndDate, dbo.vCampaigns.OwnerId,
dbo.vCampaigns.OwnerType, dbo.vCampaigns.HiddenInGeneralList, dbo.vCampaigns.HiddenInOwnerList, wf.CampaignWorkflow.ApplicationModeTypeId,
dbo.vCampaigns.SalesRep, dbo.vCampaigns.AdvertiserName,
-- new values
dbo.vCampaigns.FullName, dbo.vCampaigns.Email, dbo.vCampaigns.ContactId
FROM wf.CampaignWorkflow INNER JOIN
dbo.vCampaigns ON wf.CampaignWorkflow.CampaignId = dbo.vCampaigns.CampaignId
ORDER BY wf.CampaignWorkflow.CampaignWorkflowId DESC
Также я просто попытался добавить только существующий столбец в качестве псевдонима (дубликата): dbo.vCampaigns.AdvertiserName Результат для следующего 24-го столбца \ свойства такой же — ошибка 3002
В свойствах этого поля EntityKey — false, а Nullable — true.
Я также добавляю сюда еще одно представление, из которого я беру свои ценности:
SELECT cam.Campaign.CampaignId, cam.Campaign.OrgId, cam.Campaign.OwnerId, cam.Campaign.AccountId,
-- here they are
cam.Campaign.ContactId, SalesRep.FullName, SalesRep.Email,
cam.Campaign.AgencyId,
cam.Campaign.CampaignName, Advertiser.AccountName, Agency.AccountName AS AgencyName, cam.CampaignStatus.Code AS Type,
cam.Campaign.OwnerType, cam.Campaign.StartDate, cam.Campaign.EndDate, dbo.fnGetCampaignRunStatus(cam.Campaign.CampaignId, NULL)
AS Status, wf.CampaignWorkflow.StateMessage, wf.CampaignWorkflow.CampaignWorkflowId, cam.Campaign.TotalBudget,
cam.Campaign.HiddenInGeneralList, cam.Campaign.HiddenInOwnerList, cam.Campaign.Note,
CASE WHEN wf.CampaignWorkflow.ApplicationModeTypeId = 2 THEN CASE WHEN SalesRep.ContactId IS NULL
THEN Owner.FullName ELSE SalesRep.FullName END ELSE CASE WHEN SalesRep.ContactId IS NULL
THEN 'N/A' ELSE SalesRep.FullName END END AS SalesRep, CASE WHEN wf.CampaignWorkflow.ApplicationModeTypeId IS NULL
THEN 1 ELSE wf.CampaignWorkflow.ApplicationModeTypeId END AS ApplicationModeTypeId,
con.CustomListItem.CustomListItemName AS AdvertiserName, cam.Campaign.ClientOrderId
FROM cam.Campaign INNER JOIN
org.Account AS Advertiser ON cam.Campaign.AccountId = Advertiser.AccountId INNER JOIN
cam.CampaignStatus ON cam.Campaign.CampaignStatusId = cam.CampaignStatus.CampaignStatusId INNER JOIN
con.Contact AS Owner ON cam.Campaign.OwnerId = Owner.ContactId LEFT OUTER JOIN
con.CustomListItem ON cam.Campaign.AdvertiserId = con.CustomListItem.CustomListItemId LEFT OUTER JOIN
wf.CampaignWorkflow ON cam.Campaign.CampaignId = wf.CampaignWorkflow.CampaignId LEFT OUTER JOIN
org.Account AS Agency ON cam.Campaign.AgencyId = Agency.AccountId AND cam.Campaign.AgencyId = Agency.AccountId LEFT OUTER JOIN
con.Contact AS SalesRep ON cam.Campaign.SalesRepId = SalesRep.ContactId