我有一个函数,它返回一个tweet列表。列表中的每个元素都有大量的数据,tweet的文本、位置、用户信息(如果是转发)、它的时间、转发信息、图片链接,以及更多的数据,相互之间的数据列表。
我使用的是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‘坐标’没有定义键。定义此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‘类别’是基于没有定义键的“类别”类型。
该课程如下所示:
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包。
发布于 2017-08-16 09:22:10
这种方法行不通。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,
...
}
LinqtoTwitter将其转换为Tweet
类型,而Tweet
类型有几个习惯用法,使构建LINQ where
子句更加容易。Tweet
仍然是分层的。
要理解Tweet
的层次结构,请注意上面的JSON在Tweet
下有更复杂的对象,例如retweeted_status
( LINQ中的RetweetedStatus),它是Tweet
的Tweet
类型属性,user
是Tweet
的User
类型属性。在RetweetedStatus
和User
中是更复杂的对象。
对于您所看到的问题,请注意coordinates
属性。它没有ID
,因为它主要是一个值。也许它会更好地被建模为一个结构,因为它的语义,也许这是我的其中之一,在这里,但事实是,它没有,也永远不会,有一个ID
。如果您查看错误消息中的项列表,您将看到大多数错误都是针对像coordinates
这样的值类型对象的。
一种方法是不要在关系模型中持久化,而是寻找一个满足您需要的NoSQL选项。比如MongoDB或微软的新CosmosDB --还有无数的选择。我在自己的代码中采用了这种方法,因为虽然Twitter最近变得更加规范,但它过去常常会发生不可预测的变化。尽管如此,如今一种关系式的方法可能是可行的。在这种方法中,您可以像下面这样从Twitter读取原始内容:
string jsonResults = vontex.RawResults;
然后,您可以使用Json.NET提取单独的tweet。
下面是我将使用关系方法所做的工作:
Tweet
对象。Tweet
到User
的引用。coordinates
,则将其压缩到Tweet
中。如果它是一个多值的,比如entities
,那么创建一个单独的表,其中实体有它自己的伪键,并引用到Tweet
。我知道你想看代码。然而,这是一项巨大的工作,编写代码将与我为您编写整个数据访问层相媲美,这对于论坛的回答来说是不合理的。除非需要进行关系处理,否则我仍然会选择NoSQL路径。希望这能有所帮助。
发布于 2017-08-16 01:30:38
如果计划手动创建if,可以从状态继承并添加类似的内容:
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
或者使用注释中的键属性(http://www.entityframeworktutorial.net/code-first/key-dataannotations-attribute-in-code-first.aspx)
[Key]
public Guid Id { get; set; }
希望能帮上忙。
发布于 2017-08-16 02:30:24
你看过System.Data.Entity.ModelConfiguration.EntityTypeConfiguration吗
您可以创建一个地图:
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());
}
https://stackoverflow.com/questions/45709321
复制相似问题