【问题标题】:Setting up an Entity Framework object that contains a collection设置包含集合的实体框架对象
【发布时间】:2021-04-07 18:23:22
【问题描述】:

我的Customer 类包含我的Card 类的集合。我不确定如何将这种关系表达到 Entity Framework。

我收到以下错误:

没有为实体类型“卡片”找到合适的构造函数。以下构造函数具有无法绑定到实体类型属性的参数:无法绑定“id”、“cardBrand”、“last4”、“expMonth”、“expYear”、“cardholderName”、“billingAddress”、“fingerprint” , 'cardType', 'prepaidType', 'bin' in 'Card(string id, string cardBrand, string last4, Nullable expMonth, Nullable expYear, string cardholderName, Address billingAddress, string指纹, string cardType, string prepaidType, string bin)' .

客户类别:

public class Customer
{
    public Customer(string id = null, string createdAt = null, string updatedAt = null, IList<Card> cards = null, string givenName = null, string familyName = null, string nickname = null, string companyName = null, string emailAddress = null, Address address = null, string phoneNumber = null, string birthday = null, string referenceId = null, string note = null, CustomerPreferences preferences = null, IList<CustomerGroupInfo> groups = null, string creationSource = null, IList<string> groupIds = null, IList<string> segmentIds = null);

    [JsonProperty("group_ids", NullValueHandling = NullValueHandling.Ignore)]
    public IList<string> GroupIds { get; }
    [JsonProperty("creation_source", NullValueHandling = NullValueHandling.Ignore)]
    public string CreationSource { get; }
    [JsonProperty("groups", NullValueHandling = NullValueHandling.Ignore)]
    public IList<CustomerGroupInfo> Groups { get; }
    [JsonProperty("preferences", NullValueHandling = NullValueHandling.Ignore)]
    public CustomerPreferences Preferences { get; }
    [JsonProperty("note", NullValueHandling = NullValueHandling.Ignore)]
    public string Note { get; }
    [JsonProperty("reference_id", NullValueHandling = NullValueHandling.Ignore)]
    public string ReferenceId { get; }
    [JsonProperty("birthday", NullValueHandling = NullValueHandling.Ignore)]
    public string Birthday { get; }
    [JsonProperty("phone_number", NullValueHandling = NullValueHandling.Ignore)]
    public string PhoneNumber { get; }
    [JsonProperty("address", NullValueHandling = NullValueHandling.Ignore)]
    public Address Address { get; }
    [JsonProperty("email_address", NullValueHandling = NullValueHandling.Ignore)]
    public string EmailAddress { get; }
    [JsonProperty("company_name", NullValueHandling = NullValueHandling.Ignore)]
    public string CompanyName { get; }
    [JsonProperty("nickname", NullValueHandling = NullValueHandling.Ignore)]
    public string Nickname { get; }
    [JsonProperty("family_name", NullValueHandling = NullValueHandling.Ignore)]
    public string FamilyName { get; }
    [JsonProperty("given_name", NullValueHandling = NullValueHandling.Ignore)]
    public string GivenName { get; }
    [JsonProperty("cards", NullValueHandling = NullValueHandling.Ignore)]
    public IList<Card> Cards { get; }
    [JsonProperty("updated_at", NullValueHandling = NullValueHandling.Ignore)]
    public string UpdatedAt { get; }
    [JsonProperty("created_at", NullValueHandling = NullValueHandling.Ignore)]
    public string CreatedAt { get; }
    [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
    public string Id { get; }
    [JsonProperty("segment_ids", NullValueHandling = NullValueHandling.Ignore)]
    public IList<string> SegmentIds { get; }

    public override bool Equals(object obj);
    public override int GetHashCode();
    public Builder ToBuilder();
    public override string ToString();
    protected void ToString(List<string> toStringOutput);

    public class Builder
    {
        public Builder();

        public Builder Address(Address address);
        public Builder Birthday(string birthday);
        public Customer Build();
        public Builder Cards(IList<Card> cards);
        public Builder CompanyName(string companyName);
        public Builder CreatedAt(string createdAt);
        public Builder CreationSource(string creationSource);
        public Builder EmailAddress(string emailAddress);
        public Builder FamilyName(string familyName);
        public Builder GivenName(string givenName);
        public Builder GroupIds(IList<string> groupIds);
        public Builder Groups(IList<CustomerGroupInfo> groups);
        public Builder Id(string id);
        public Builder Nickname(string nickname);
        public Builder Note(string note);
        public Builder PhoneNumber(string phoneNumber);
        public Builder Preferences(CustomerPreferences preferences);
        public Builder ReferenceId(string referenceId);
        public Builder SegmentIds(IList<string> segmentIds);
        public Builder UpdatedAt(string updatedAt);
    }
}

我的卡类:

public class Card
{
    public Card(string id = null, string cardBrand = null, string last4 = null, long? expMonth = null, long? expYear = null, string cardholderName = null, Address billingAddress = null, string fingerprint = null, string cardType = null, string prepaidType = null, string bin = null);

    [JsonProperty("prepaid_type", NullValueHandling = NullValueHandling.Ignore)]
    public string PrepaidType { get; }
    [JsonProperty("card_type", NullValueHandling = NullValueHandling.Ignore)]
    public string CardType { get; }
    [JsonProperty("fingerprint", NullValueHandling = NullValueHandling.Ignore)]
    public string Fingerprint { get; }
    [JsonProperty("billing_address", NullValueHandling = NullValueHandling.Ignore)]
    public Address BillingAddress { get; }
    [JsonProperty("cardholder_name", NullValueHandling = NullValueHandling.Ignore)]
    public string CardholderName { get; }
    [JsonProperty("exp_year", NullValueHandling = NullValueHandling.Ignore)]
    public long? ExpYear { get; }
    [JsonProperty("exp_month", NullValueHandling = NullValueHandling.Ignore)]
    public long? ExpMonth { get; }
    [JsonProperty("last_4", NullValueHandling = NullValueHandling.Ignore)]
    public string Last4 { get; }
    [JsonProperty("card_brand", NullValueHandling = NullValueHandling.Ignore)]
    public string CardBrand { get; }
    [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
    public string Id { get; }
    [JsonProperty("bin", NullValueHandling = NullValueHandling.Ignore)]
    public string Bin { get; }

    public override bool Equals(object obj);
    public override int GetHashCode();
    public Builder ToBuilder();
    public override string ToString();
    protected void ToString(List<string> toStringOutput);

    public class Builder
    {
        public Builder();

        public Builder BillingAddress(Address billingAddress);
        public Builder Bin(string bin);
        public Card Build();
        public Builder CardBrand(string cardBrand);
        public Builder CardholderName(string cardholderName);
        public Builder CardType(string cardType);
        public Builder ExpMonth(long? expMonth);
        public Builder ExpYear(long? expYear);
        public Builder Fingerprint(string fingerprint);
        public Builder Id(string id);
        public Builder Last4(string last4);
        public Builder PrepaidType(string prepaidType);
    }
}

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    实体框架类:仅限 POCO!

    问题是您的类型没有默认构造函数,就像错误所说的那样。

    使用实体框架时,类代表您的表以及表之间的关系。它们应该是简单的 POCO(普通的旧 CRL 对象)。所以:

    • 没有构造函数
    • 没有字段
    • 仅获取/设置属性
    • 最好没有方法,毕竟:类代表你的表,表没有任何方法

    POCO classes in entity framework

    This tutorial helped me a lot to understand how to use entity framework

    实体框架中的一对多

    因此,您想在CustomersCards 之间创建一对多关系:每个Customer 都有零个或多个Cards,每个Card 恰好属于一个Customer

    在实体框架中,您可以使用以下类对其进行建模:

    public class Customer
    {
        public int Id {get; set;}
        public string Name {get; set;}
        ...
    
        // Every Customer has zero or more Cards (one-to-many)
        public virtual ICollection<Card> Cards {get; set;}
    }
    
    public class Card
    {
        public int Id {get; set;}
        public string Name {get; set;}
        ...
    
        // Every Card is a Card of exactly one Customer, using foreign key:
        public int CustomerId {get; set;}
        public virtual Customer Customer {get; set;}
    }
    

    当然还有 DbContext:

    public class CustomerDbContext : DbContext
    {
        public DbSet<Customer> Customers {get; set;}
        public DbSet<Card> Cards {get; set;}
    }
    

    因为我遵循entity framework conventions, 尤其是那些关于复数和虚拟ICollections 的,实体框架会自动检测表、表中的列和一对多关系。

    在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多、多对多)。

    外键CustomerId是Cards表中的实列,所以不是虚Cards。Customer不是列,表示Card和Customer的关系,所以是虚的

    顺便说一句:我把它设为virtual ICollection&lt;Card&gt;,而不是某种List,因为Card[4]在获取数据后没有定义的含义,而像Add/Remove这样的ICollection方法确实有定义的含义。

    只有当我想偏离约定时:不同的表名,或不同的列标识符,或它们的类型,才需要一些 fluent API 的属性。

    不过,如果您想在DbContext.OnModelCreating 中将一对多关系指定为流畅的 API,请使用以下内容:

    // Every Customer has zero or more Cards, using foreign key (one-to-many)
    modelBuilder.Entity<Customer>().HasMany(customer => customer.Cards)
        .WithRequired(card => card.Customer)
        .HasForeignKey(card => card.CustomerId);
    

    简而言之:Customers 表中的每个客户都有零个或多个 Cards,通过属性 Customer.Cards。每张卡通过属性 Card.Customer 完全属于一个客户。在数据库中,这是强制使用外键 Card.CustomerId。

    【讨论】:

    • 很好的答案,我现在很明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多