我有一个返回推文列表的函数。该列表中的每个元素都有大量数据,推文的文本,位置,用户信息,如果是转推,它的时间,转发信息,图片链接和更多数据,彼此之间的数据列表列表。
我正在使用Linq2Twitter包,它为我提供了一个名为Status的对象,这就是我所说的Tweet。
此代码从我的函数中获取数据:var container = await DoPagedSearchAsync(context, this);
我的DBSet看起来像这样:
public class TweetContext : DbContext
{
public DbSet<Status> Tweets { get; set; }
}
我正在尝试使用此代码添加数据:
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'Coordinate'没有定义键。定义此EntityType的键。 DataAcquirer.Models.Entities :: EntityType'Entities'没有定义键。 &gt;定义此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'RisualEntity'没有定义键。定义此EntityType的键。 DataAcquirer.Models.UrlEntity :: EntityType'UrlEntity'没有定义键。定义此EntityType的键。 DataAcquirer.Models.UserMentionEntity :: EntityType'UserMentionEntity'没有定义键。定义此EntityType的键。 DataAcquirer.Models.Geometry :: EntityType'Geometry'没有定义键。定义此EntityType的键。 DataAcquirer.Models.User :: EntityType'User'没有定义键。定义此EntityType的键。 DataAcquirer.Models.BannerSize :: EntityType'BandateSize'没有定义键。定义此EntityType的键。 DataAcquirer.Models.Category :: EntityType'Categage'没有定义键。定义此EntityType的键。 推文:EntityType:EntitySet'推文'基于类型'状态',没有定义键。 坐标:EntityType:EntitySet“坐标”基于没有定义键的“坐标”类型。 实体:EntityType:EntitySet“实体”基于没有定义键的“实体”类型。 HashTagEntities:EntityType:EntitySet'HashTagEntities'基于类型'HashTagEntity',没有定义键。 PhotoSizes:EntityType:EntitySet'PhotoSizes'基于类型'PhotoSize',没有定义键。 VideoInfoes:EntityType:EntitySet'VideoInfoes'基于没有定义键的类型'VideoInfo'。 变体:EntityType:EntitySet'Variants'基于没有定义键的'Variant'类型。 SymbolEntities:EntityType:EntitySet'RisualEntities'基于没有定义键的类型'SymbolEntity'。 UrlEntities:EntityType:EntitySet'UrlEntities'基于类型'UrlEntity',没有定义键。 UserMentionEntities:EntityType:EntitySet'UserMentionEntities'基于没有定义键的'UserMentionEntity'类型。 几何:EntityType:EntitySet'Geometries'基于没有定义键的'Geometry'类型。 用户:EntityType:EntitySet'Users'基于没有定义键的'User'类型。 BannerSizes:EntityType:EntitySet'BrainSizes'基于没有定义键的类型'BannerSize'。 类别:EntityType:EntitySet'Categories'基于没有定义键的类型'Category'。
该课程类似于以下内容:
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软件包。
答案 0 :(得分:1)
这种方法不起作用。 Twitter API返回分层而非关系的对象。例如这里是LINQ to Twitter消费的片段:
{
"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,
...
}
LINQ to Twitter将其转换为Tweet
类型,Tweet
类型有一些习惯用语,以便更容易构建LINQ where
子句。 Tweet
仍然是分层的。
要理解Tweet
的层次结构,请注意上面的JSON在Tweet
下面有更复杂的对象,例如retweeted_status
(在LINQ to Twitter中转发的状态),这是Tweet
的{{1}}类型属性,以及Tweet
的{{1}}类型属性user
。在User
和Tweet
内是更复杂的对象。
针对您所看到的问题,请注意RetweetedStatus
属性。它没有User
,因为它主要是一个值。也许它本来可以更好地建模为它的语义结构,也许这是我在这里的一个外卖,但事实是它没有,也永远不会有coordinates
。如果您浏览错误消息中的项目列表,则会发现大多数错误都适用于ID
等值类型对象。
一种方法是不要在关系模型中持久存在并寻找满足您需求的NoSQL选项。例如MongoDB或微软的新CosmosDB - 有无数的选择。我在自己的代码中采用了这种方法,因为虽然Twitter API现在更加严谨,但它过去常常无法改变。也就是说,近来关系方法可能是可行的。在这种方法中,您可以从Twitter读取原始内容,如下所示:
ID
然后你可以使用Json.NET推出个人推文。
这是我用关系方法做的事情:
coordinates
对象。string jsonResults = vontex.RawResults;
到Tweet
的参考。Tweet
,则将其展平为User
。
湾如果它是一个多值,例如coordinates
,则创建一个单独的表,其中实体拥有它自己的伪密钥并返回Tweet
。我知道你想看代码。然而,这是一项巨大的工作,编写代码可以与我为您编写整个数据访问层相媲美,这对于论坛答案来说是不合理的。我仍然会继续使用NoSQL路线,除非有很难要求关系。希望这会有所帮助。
答案 1 :(得分:0)
如果您打算手动创建ID,可以从状态继承并添加类似的内容:
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
或在评论中使用Key属性(http://www.entityframeworktutorial.net/code-first/key-dataannotations-attribute-in-code-first.aspx)
[Key]
public Guid Id { get; set; }
我希望它有所帮助。
答案 2 :(得分:0)
您可以创建地图:
public class StatusMap : EntityTypeConfiguration<Status>
{
public StatusMap()
{
ToTable("StatusTable")
.HasKey(p => p.ID);
}
}
然后在你的上下文中添加:
protected override void OnModelCreating([NotNull] DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new StatusMap());
}