Обязательный столбец CustomerId не присутствовал в результатах операции FromSql - PullRequest
0 голосов
/ 26 февраля 2019

Сообщение об ошибке ясно:

'Обязательный столбец' CustomerId 'не присутствовал в результатах операции' FromSql '

Но как-то ядействительно не ожидал CustomerId?

Ошибка происходит здесь:

contacts = db.Contacts.FromSql("SIP_API_MONDIA_Contacts_sel").ToList();
addresses = db.Addresses.FromSql("SIP_API_MONDIA_Address_sel").ToList();

Контроллер:

  public IList<Customer> GetAllCustomers()
        {
            //Initialize the objects
            IList<Customer> customers = null;
            IList<Contacts> contacts = null;
            IList<Addresses> addresses = null;

            //Fetch the data from stored procedures
            customers = db.Customers.FromSql("SomeProcName").ToList();
            contacts = db.Contacts.FromSql("SomeProcName").ToList();
            addresses = db.Addresses.FromSql("SomeProcName").ToList();

            //Loop through customers and add the contact and addresses when required
            foreach(var item in customers)
            {
                item.Contacts = contacts.Where(x => x.Customer == item.Id).ToList();
                item.Addresses = addresses.Where(x => x.Customer == item.Id).ToList();
            }
            return customers;
        }

Модель:

public class Customer
    {
        public Guid Id { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
        public string VatCode { get; set; }
        public string ChamberOfCommerceCode { get; set; }
        public DateTime Modified { get; set; }
        public DateTime Created { get; set; }
        public string LanguageCode { get; set; }
        public decimal Discount { get; set; }
        public string CustomerManager { get; set; }
        public Guid PriceList { get; set; }
        public Guid PaymentCondition { get; set; }
       // public bool VatLiable { get; set; }
        public bool IsBlocked { get; set; }
        public bool IsProspect { get; set; }
        public bool IsSuspect { get; set; }
        public string Website { get; set; }
        public string DashboardUrl { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Fax { get; set; }
        //     public ICollection<FreeFields> FreeFields { get; set; }
        //      public Dictionary<string, string> UknownElements { get; set; }
        public ICollection<Contacts> Contacts { get; set; }
        public ICollection<Addresses> Addresses { get; set; }
    }

    public class FreeFields
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }

    public class Contacts
    {
        public Guid Id { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public string Initials { get; set; }
        public string Function { get; set; }    
        public Guid Customer { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Mobile { get; set; }
        public string LanguageCode { get; set; }
        public bool IsMainContact { get; set; }
        public string Gender { get; set; }
        public string Username { get; set; }
    }
    public class Addresses
    {
        public Guid Id { get; set; }
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string AddressLine3 { get; set; }
        public string Postcode { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
        public string CountryCode { get; set; }
        public string Type { get; set; }
        public Guid Customer { get; set; }// This Property should be GUID instead of String..
        public bool IsMainAddress { get; set; }
        public string Route { get; set; }
        public string State { get; set; }
    }

Я не совсем уверен, что означает ошибка с 'CustomerId'. Хранимые процедуры возвращают 100% точное значение моделей.

Правка для добавления вывода на печать набора результатов sql && DbContext:

public class IsahContext : DbContext
    {
        public  IsahContext()
        {

        }

        public IsahContext(DbContextOptions<IsahContext> options)
            : base(options)
        {
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer(Setting.ConnectionString);
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
        }

        //Entities will come here 
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Addresses> Addresses { get; set; }
        public DbSet<Contacts> Contacts { get; set; }

    }

enter image description here

enter image description here

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

CustomerId - это условное имя для внешнего ключа отношений «один ко многим», введенное в свойствах навигации коллекции

public ICollection<Contacts> Contacts { get; set; }
public ICollection<Addresses> Addresses { get; set; }

класса Customer.

Хотя связанные классы Contacts и Addresses содержат свойство Guid Customer, из-за его имени оно не распознается как внешний ключ, поэтому оно попадает в Нет свойства внешнего ключа категория.И EF Core принимает теневое свойство (и столбец) с именем CustomerId. Соглашение о свойствах теней Объяснение таково:

Свойства теней могут создаваться соглашением, когда обнаруживается связь, но в классе зависимого объекта не найдено свойство внешнего ключа.В этом случае будет введено свойство внешнего ключа.Свойство теневого внешнего ключа будет иметь имя <navigation property name><principal key property name> (для именования используется навигация по зависимому объекту, которая указывает на главный объект).Если имя свойства основного ключа включает в себя имя свойства навигации, тогда оно будет просто <principal key property name>.Если у зависимого объекта нет свойства навигации, то вместо него используется имя основного типа.

Чтобы отобразить свойство Customer как FK, следует использовать либо * 1025Атрибут * ForeignKey :

Аннотации данных можно использовать, чтобы указать, какое свойство следует использовать в качестве свойства внешнего ключа для данного отношения.Обычно это делается, когда свойство внешнего ключа не обнаружено соглашением.

Совет
Аннотация [ForeignKey] может быть помещена в любое свойство навигации в отношении.Не требуется переходить к свойству навигации в классе зависимых объектов.

Например (поскольку у вас нет свойства навигации в зависимых объектах):

[ForeignKey(nameof(Contacts.Customer))]
public ICollection<Contacts> Contacts { get; set; }

[ForeignKey(nameof(Addresses.Customer))]
public ICollection<Addresses> Addresses { get; set; }

или Свободный API :

modelBuilder.Entity<Customer>()
    .HasMany(customer => customer.Contacts)
    .WithOne() // no nav property
    .HasForeignKey(contact => contact.Customer); // the FK property

modelBuilder.Entity<Customer>()
    .HasMany(customer => customer.Addresses)
    .WithOne() // no nav property
    .HasForeignKey(address => address.Customer); // the FK property
0 голосов
/ 26 февраля 2019

Не могли бы вы также опубликовать соответствующие части класса контекста БД и пример результата хранимой процедуры.

Без них я могу только догадываться:

Столбец Identity не являетсяпомечены атрибутом [Key] и не соответствуют стандартному соглашению об именах «EntityNameId», поэтому он не может вычесть столбец идентификаторов.

Итак, я предлагаю добавить атрибут [Key] в Id свойство:

[Key]
public Guid Id { get; set; }

Если это не сработает, пожалуйста, опубликуйте контекст и результат SP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...