首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架添加重复的外键

实体框架添加重复的外键
EN

Stack Overflow用户
提问于 2020-04-12 15:32:15
回答 1查看 37关注 0票数 0

我有两个实体

代码语言:javascript
复制
public class CandlestickData
{
    [Key]
    public int Id { get; set; }
    public virtual Symbol Symbol { get; set; }
    [Column(TypeName = "datetime2")]
    public DateTime Time { get; set; }
    public decimal Open { get; set; }
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal Close { get; set; }
}

代码语言:javascript
复制
public class Symbol
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
}

因为我每分钟在数据库中添加很多'CandlestickData‘,并且符号通常是相同的,并且不会被更改,所以我想避免对数据库的无用调用,所以我做了一个扩展方法,将已经从数据库中检索到的符号保存在一个列表中,这样我就可以重用它们。

代码语言:javascript
复制
public static class Extension
    {
        static List<Symbol> ExistingSymbols = new List<Symbol>();
        public static Symbol GetSymbolIfExistsOrCreateItInTheDb(this string name, Repository repository)
        {
            if (ExistingSymbols.Any(x => x.Name == name))
            {
                return ExistingSymbols.First(x => x.Name == name);
            }
            if (repository.SymbolExists(name))
            {
                var symbol = repository.GetSymbol(name);
                ExistingSymbols.Add(symbol);
                return symbol;
            }
            else
            {
                Symbol symbol = new Symbol { Name = name };
                repository.AddSymbol(symbol);
                symbol = repository.GetSymbol(name);
                ExistingSymbols.Add(symbol);
                return symbol;
            }
        }
    }

这是在数据库中添加多个'CandlestickData‘的代码

代码语言:javascript
复制
using (var repository = new Repository())
            {
                var candlesticks = new List<CandlestickData>();
                foreach (var symbol in AllSymbolsTradeData[GetNotUsedIndex()])
                {
                    candlesticks.Add(new CandlestickData
                    {
                        Close = symbol.Value.Close,
                        Symbol = symbol.Key.GetSymbolIfExistsOrCreateItInTheDb(repository),
                        High = symbol.Value.High,
                        Low = symbol.Value.Low,
                        Open = symbol.Value.Open,
                        Time = symbol.Value.Time
                    });
                }
                repository.AddCandlesticksData(candlesticks);
                repository.CommitChanges();
            }

另外,如果您想查看Repository类的外观:

代码语言:javascript
复制
public class Repository : IDisposable
    {
        private Db context;
        public Repository()
        {
            context = new Db();
        }

        public bool SymbolExists(string name)
        {
            return context.Symbols.Where(x => x.Name == name).Any();
        }
        public Symbol GetSymbol(string name)
        {
            return context.Symbols.First(x => x.Name == name);
        }
        public void AddSymbol(Symbol symbol)
        {
            context.Symbols.Add(symbol);
            context.SaveChanges();
        }
        public void AddCandlestickData(CandlestickData candlestickData)
        {
            context.Candlesticks.Add(candlestickData);
        }
        public void AddCandlesticksData(List<CandlestickData> candlesticks)
        {
            context.Candlesticks.AddRange(candlesticks);
        }

        public void CommitChanges()
        {
            context.SaveChanges();
        }

        public void Dispose()
        {
            context.Dispose();
        }
    }

现在我的问题是,每次我的扩展方法从内存列表中获取符号(带有ID和名称),在调用CommitChanges方法之后,从我的列表中使用的引用符号获得另一个ID,并且在数据库中插入一个具有相同名称但具有新ID的新符号。

当我每次从数据库获取符号时,我的代码工作正常(没有在数据库中创建重复),并且我找不到我做错了什么,因为列表中存储的符号是具有正确ID的数据库中的符号……

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-12 15:48:10

问题是,ExistingSymbols加载到的DbContext与保存烛台的上下文不同。

这是因为ExistingSymbols是静态的,它用于多个操作,从而节省了大量的开销。

你可以通过修改CandlestickData的模型来添加一个外键来解决这个问题:

代码语言:javascript
复制
public class CandlestickData
{

    public int SymbolId { get; set; }

    [ForeignKey(nameof(SymbolId))]
    public virtual Symbol Symbol { get; set; }

然后在使用符号创建新对象时只使用外键:

代码语言:javascript
复制
candlesticks.Add(new CandlestickData
{
    Close = symbol.Value.Close,
    SymbolId = symbol.Key.GetSymbolIfExistsOrCreateItInTheDb(repository).Id,
    High = symbol.Value.High,
    Low = symbol.Value.Low,
    Open = symbol.Value.Open,
    Time = symbol.Value.Time
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61168160

复制
相关文章

相似问题

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