首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >实体框架在添加没有ID的数据时抛出错误

实体框架在添加没有ID的数据时抛出错误
EN

Stack Overflow用户
提问于 2017-08-16 09:03:05
回答 3查看 282关注 0票数 1

我有一个函数,它返回一个tweet列表。列表中的每个元素都有大量的数据,tweet的文本、位置、用户信息(如果是转发)、它的时间、转发信息、图片链接,以及更多的数据,相互之间的数据列表。

我使用的是Linq2Twitter包,它为我提供了一个名为Status的对象,这就是我所指的Tweet。

这段代码从我的函数:var container = await DoPagedSearchAsync(context, this);中获取数据

我的DBSet看起来是这样的:

代码语言:javascript
代码运行次数:0
运行
复制
       public class TweetContext : DbContext
    {
        public DbSet<Status> Tweets { get; set; }
    }

我试图用以下代码添加数据:

代码语言:javascript
代码运行次数:0
运行
复制
        using (var vontex = new TweetContext())
        {
            vontex.Tweets.AddRange(container);
            vontex.SaveChanges();
        }

下面是我在运行时在行中得到的错误列表:vontex.Tweets.AddRange(container);

在模型生成过程中检测到一个或多个验证错误: DataAcquirer.Models.Status::EntityType 'Status‘没有定义键。定义此EntityType的键。DataAcquirer.Models.Coordinate::EntityType‘坐标’没有定义键。定义此EntityType的键。DataAcquirer.Models.Entities::EntityType‘实体’没有定义密钥。>定义此EntityType的键。DataAcquirer.Models.HashTagEntity::EntityType 'HashTagEntity‘没有定义键。定义此EntityType的键。DataAcquirer.Models.PhotoSize::EntityType 'PhotoSize‘没有定义键。定义此EntityType的键。DataAcquirer.Models.VideoInfo::EntityType 'VideoInfo‘没有定义键。定义此EntityType的键。DataAcquirer.Models.Variant::EntityType 'Variant‘没有定义键。定义此EntityType的键。DataAcquirer.Models.SymbolEntity::EntityType 'SymbolEntity‘没有定义键。定义此EntityType的键。DataAcquirer.Models.UrlEntity::EntityType 'UrlEntity‘没有定义键。定义此EntityType的键。DataAcquirer.Models.UserMentionEntity::EntityType 'UserMentionEntity‘没有定义键。定义此EntityType的键。DataAcquirer.Models.Geometry::EntityType‘几何学’没有定义键。定义此EntityType的键。DataAcquirer.Models.User::EntityType 'User‘没有定义密钥。定义此EntityType的键。DataAcquirer.Models.BannerSize::EntityType 'BannerSize‘没有定义键。定义此EntityType的键。DataAcquirer.Models.Category::EntityType‘EntityType’类别没有定义键。定义此EntityType的键。推特: EntityType: EntitySet 'Tweets‘是基于没有定义键的“状态”类型的。坐标: EntityType: EntitySet‘坐标’基于没有定义键的“坐标”类型。实体: EntityType: EntitySet‘实体’是基于没有定义键的“实体”类型的。HashTagEntities: EntityType: EntitySet 'HashTagEntities‘是基于没有定义键的'HashTagEntity’类型的。PhotoSizes: EntityType: EntitySet 'PhotoSizes‘是基于没有定义键的'PhotoSize’类型的。VideoInfoes: EntityType: EntitySet 'VideoInfoes‘是基于没有定义键的'VideoInfo’类型的。变体: EntityType: EntitySet 'Variants‘是基于没有定义键的类型’Variants‘。SymbolEntities: EntityType: EntitySet 'SymbolEntities‘是基于没有定义键的'SymbolEntity’类型的。UrlEntities: EntityType: EntitySet 'UrlEntities‘是基于没有定义键的'UrlEntity’类型的。UserMentionEntities: EntityType: EntitySet 'UserMentionEntities‘是基于没有定义键的'UserMentionEntity’类型的。几何: EntityType: EntitySet‘几何学’是基于没有定义键的类型‘几何学’。EntityType: EntitySet 'User‘是基于没有定义键的’User‘类型的。BannerSizes: EntityType: EntitySet 'BannerSizes‘是基于没有定义键的'BannerSize’类型的。类别: EntityType: EntitySet‘类别’是基于没有定义键的“类别”类型。

该课程如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using LitJson;

namespace LinqToTwitter
{
 [XmlType(Namespace = "LinqToTwitter")]
 public class Status
 {
    public Status();
    public Status(JsonData status);

    public Annotation Annotation { get; set; }
    public List<Contributor> Contributors { get; set; }
    public Coordinate Coordinates { get; set; }
    public int Count { get; set; }
    public DateTime CreatedAt { get; set; }
    public ulong CurrentUserRetweet { get; set; }
    public long Cursor { get; set; }
    public Cursors CursorMovement { get; set; }
    public EmbeddedStatus EmbeddedStatus { get; set; }
    public Entities Entities { get; set; }
    public bool ExcludeReplies { get; set; }
    public Entities ExtendedEntities { get; set; }
    public int? FavoriteCount { get; set; }
    public bool Favorited { get; set; }
    public FilterLevel FilterLevel { get; set; }
    public ulong ID { get; set; }
    public bool IncludeContributorDetails { get; set; }
    public bool IncludeEntities { get; set; }
    public bool IncludeMyRetweet { get; set; }
    public bool IncludeRetweets { get; set; }
    public bool IncludeUserEntities { get; set; }
    public string InReplyToScreenName { get; set; }
    public ulong InReplyToStatusID { get; set; }
    public ulong InReplyToUserID { get; set; }
    public string Lang { get; set; }
    public bool Map { get; set; }
    public ulong MaxID { get; set; }
    public StatusMetaData MetaData { get; set; }
    public EmbeddedStatusAlignment OEmbedAlign { get; set; }
    public bool OEmbedHideMedia { get; set; }
    public bool OEmbedHideThread { get; set; }
    public string OEmbedLanguage { get; set; }
    public int OEmbedMaxWidth { get; set; }
    public bool OEmbedOmitScript { get; set; }
    public string OEmbedRelated { get; set; }
    public string OEmbedUrl { get; set; }
    public Place Place { get; set; }
    public bool PossiblySensitive { get; set; }
    public Status QuotedStatus { get; set; }
    public ulong QuotedStatusID { get; set; }
    public int RetweetCount { get; set; }
    public bool Retweeted { get; set; }
    public Status RetweetedStatus { get; set; }
    [XmlIgnore]
    public Dictionary<string, string> Scopes { get; set; }
    public string ScreenName { get; set; }
    public ulong SinceID { get; set; }
    public string Source { get; set; }
    public ulong StatusID { get; set; }
    public string Text { get; set; }
    public bool TrimUser { get; set; }
    public bool Truncated { get; set; }
    public string TweetIDs { get; set; }
    [XmlIgnore]
    public StatusType Type { get; set; }
    public User User { get; set; }
    public ulong UserID { get; set; }
    public List<ulong> Users { get; set; }
    public bool WithheldCopyright { get; set; }
    public List<string> WithheldInCountries { get; set; }
    public string WithheldScope { get; set; }
 }
}

以上模型不能编辑。它附带了Linq2Twitter包。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-08-16 17:22:10

这种方法行不通。Twitter返回分层而非关系的对象。下面是使用的代码片段:

代码语言:javascript
代码运行次数:0
运行
复制
{
  "retweeted":false,
  "in_reply_to_screen_name":null,
  "possibly_sensitive":false,
  "retweeted_status":{
     "retweeted":false,
     ...,
     "user":{
        "id":41754227,
        ...
     },
     ...
  },
  "contributors":null,
  "coordinates":{
      "type":"Point",
      "coordinates":[
          -122.40060,
          37.78215
      ]
  },
  "place":null,
  "user":{
     "id":15411837,
     ...
  },
  "retweet_count":393,
  ...
}

LinqtoTwitter将其转换为Tweet类型,而Tweet类型有几个习惯用法,使构建LINQ where子句更加容易。Tweet仍然是分层的。

要理解Tweet的层次结构,请注意上面的JSON在Tweet下有更复杂的对象,例如retweeted_status ( LINQ中的RetweetedStatus),它是TweetTweet类型属性,userTweetUser类型属性。在RetweetedStatusUser中是更复杂的对象。

对于您所看到的问题,请注意coordinates属性。它没有ID,因为它主要是一个值。也许它会更好地被建模为一个结构,因为它的语义,也许这是我的其中之一,在这里,但事实是,它没有,也永远不会,有一个ID。如果您查看错误消息中的项列表,您将看到大多数错误都是针对像coordinates这样的值类型对象的。

一种方法是不要在关系模型中持久化,而是寻找一个满足您需要的NoSQL选项。比如MongoDB或微软的新CosmosDB --还有无数的选择。我在自己的代码中采用了这种方法,因为虽然Twitter最近变得更加规范,但它过去常常会发生不可预测的变化。尽管如此,如今一种关系式的方法可能是可行的。在这种方法中,您可以像下面这样从Twitter读取原始内容:

代码语言:javascript
代码运行次数:0
运行
复制
string jsonResults = vontex.RawResults;

然后,您可以使用Json.NET提取单独的tweet。

下面是我将使用关系方法所做的工作:

  1. 使用自动机。学习这个工具所需的时间不多,不仅在这个项目上,而且在将来也会有很多好处。
  2. 创建适合关系持久性的自己的Tweet对象。
  3. 使用关系引用将被转发的状态引用回原始的tweet。
  4. 创建一个用户表,并创建一个从TweetUser的引用。
  5. 对于所有的值类型对象,您有两个选项: a.如果它是单个值,如coordinates,则将其压缩到Tweet中。如果它是一个多值的,比如entities,那么创建一个单独的表,其中实体有它自己的伪键,并引用到Tweet

我知道你想看代码。然而,这是一项巨大的工作,编写代码将与我为您编写整个数据访问层相媲美,这对于论坛的回答来说是不合理的。除非需要进行关系处理,否则我仍然会选择NoSQL路径。希望这能有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2017-08-16 09:30:38

如果计划手动创建if,可以从状态继承并添加类似的内容:

代码语言:javascript
代码运行次数:0
运行
复制
 [DatabaseGe‌​nerated(DatabaseGen‌​eratedOption.None)]
 public Guid Id { get; set; }

或者使用注释中的键属性(http://www.entityframeworktutorial.net/code-first/key-dataannotations-attribute-in-code-first.aspx)

代码语言:javascript
代码运行次数:0
运行
复制
[Key]
 public Guid Id { get; set; }

希望能帮上忙。

票数 0
EN

Stack Overflow用户

发布于 2017-08-16 10:30:24

你看过System.Data.Entity.ModelConfiguration.EntityTypeConfiguration

您可以创建一个地图:

代码语言:javascript
代码运行次数:0
运行
复制
public class StatusMap : EntityTypeConfiguration<Status>
{
     public StatusMap()
     {
         ToTable("StatusTable")
         .HasKey(p => p.ID);
     }
}

然后,在您的上下文中添加:

代码语言:javascript
代码运行次数:0
运行
复制
protected override void OnModelCreating([NotNull] DbModelBuilder modelBuilder)
{
     modelBuilder.Configurations.Add(new StatusMap());
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45709321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档