加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 从IEnumerable转换为ICollection

发布时间:2020-12-15 05:36:39 所属栏目:百科 来源:网络整理
导读:我正在尝试转换IEnumerable IEnumerable string到ICollection Character但由于一个物体的结构与另一个物体的结构不同,因此努力找出正确的方法. 转换的原因是采用json反序列化并通过Entity Framework将其插入到数据库中. json数据未规范化,与数据库的确切结构
我正在尝试转换IEnumerable< IEnumerable< string>>到ICollection< Character>但由于一个物体的结构与另一个物体的结构不同,因此努力找出正确的方法.

转换的原因是采用json反序列化并通过Entity Framework将其插入到数据库中. json数据未规范化,与数据库的确切结构不匹配.在数据库中,我有一部电影和一个有多对多关系的人.它们之间的桥接表是字符.但是json只有一个带有一组人物对象的电影对象,每个人都有一组他们播放的角色(IEnumerable< IEnumerable< string>>).

基本上,我需要将每部电影的人物及其角色转换为每部电影的角色及其各自的人物.

var movie = dataContractMovies.Select(m => new Movie {
    Title = m.Title,// not sure how to convert each Person and their characters
    Characters = // Need to take each Person and their Characters in m.Cast and cast to a new Character and a new Person for which the Character belongs to
});

转换自

public class MovieDataContract {
    [DataMember(Name = "title")]
    public string Title { get; set; }

    [DataMember(Name = "abridged_cast")]
    public virtual IEnumerable<Person> Cast { get; set; }
}

[DataContract]
public class Person {
    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "characters")]
    public IEnumerable<string> Characters { get; set; }
}

转换成

public partial class Movie {
    public string Title { get; set; }
    public virtual ICollection<Character> Characters { get; set; }

    public Movie() {
        this.Characters = new HashSet<Character>();
    }
}

public partial class Character {
    public string Name { get; set; }
    public virtual Movie Movie { get; set; }
    public virtual Person Person { get; set; }
}

public partial class Person {
    public string Name { get; set; }
    public virtual ICollection<Character> Characters { get; set; }

    public Person() {
        this.Characters = new HashSet<Character>();
    }
}

更新和进一步的问题

如果我刚刚添加了一个公共的IEnumerable< Character> MovieDataContract的字符?然后我可以做这样的事情(理论上,没有测试过)……

Characters = m.Characters;

所以我的新MovieDataContract看起来像这样……

[DataContract]
public class MovieDataContract {
    [DataMember(Name = "title")]
    public string Title { get; set; }

    [DataMember(Name = "abridged_cast")]
    private IEnumerable<Person> _cast { get; set; }

    public IEnumerable<Character> Characters { 
        get{  
            foreach(var person in _cast) {
                foreach(string name in person.characters) {
                    yield return new Character { Name = name,Person = new Person { Name = person.name }}
                }
            }
        } 
    }
}

解决方法

我为答案做了一些假设:1.我们只是插入新电影,而不是更新数据库中已有的电影. 2.我们正在使用实体框架来执行插入操作. 3.正在添加的电影中的人不在与其他电影相关联的数据库中.每部电影都有一个演员阵容,每个演员至少有一个角色.

冒着被冷却的小孩巴士扔掉的风险我的解决方案不使用LINQ,虽然我确信可以修改它来这样做.请注意,使用EF时,您无需设置关联的两端即可将其插入数据库.

// Lookup is necessary because a person might be in more than one movie.
var personLookup = new Dictionary<string,Person>();

foreach (var contractMovie in dataContractMovies)
{
    var movie = new Movie() { Title = contractMovie.Title };

    foreach (var contractPerson in contractMovie.Cast)
    {
        if (!personLookup.ContainsKey(contractPerson.Name))
        {
            personLookup.Add(contractPerson.Name,new Person() { Name = contractPerson.Name });
        }
        var person = personLookup[contractPerson.Name];

        foreach (var contractCharacter in contractPerson.Characters)
        {
            var character = new Character() { Name = contractCharacter.Name,Person = person,Movie = movie };

            dataContext.Characters.Add(character);
        }
    }
 }
 dataContext.SaveChanges();

如果DataContract将Movie映射到Character而不是Person(就像你在评论中建议的那样),你可以得到更像这样的东西:

var personLookup = new Dictionary<string,Person>();
var movie = dataContractMovies.Select(m => new Movie {
    Title = m.Title,Characters = m.Characters.Select(c => new Character() { Name = c.Name,Person = LookupPerson(c.Person,personLookup) }).ToList()
});

public Person LookupPerson(string personName,Dictionary<string,Person> personLookup)
{
        if (!personLookup.ContainsKey(personName))
        {
            personLookup.Add(personName,new Person() { Name = personName });
        }
        return personLookup[personName];
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读