小编Jul*_*anR的帖子

协作环境中的实体框架中的迁移

我们有多个开发人员在使用Entity Framework 5.0的项目上工作.每个开发人员都使用自己的本地SQL 2012数据库,这样他就可以开发和测试而不会妨碍其他人.

起初,我们使用了自动迁移和基于代码的迁移的混合体.这根本不起作用,所以我们决定禁用自动迁移,只允许基于代码.我应该补充一点,我们再次启动了一个干净的数据库而没有_MigrationsHistory来自所有自动迁移的"损坏" .

所以现在的工作流程是:

  1. 开发人员更改了他的数据模型
  2. 是否add-migration <Name>将其应用于他的数据库update-database.
  3. 检查数据模型更改和迁移到Git.
  4. 另一个开发人员拉动,接收更改并将其应用到他的数据库.

到目前为止,这运作良好.然而,在今天之前,通常只有我做了迁移而其他人应用了它们.但今天有来自三个开发人员的迁移.我刚刚完成了这些迁移,做了一件update-database好事.

我也对自己的数据模型进行了更改,但是在结束时update-database它给了我一个警告,我仍然没有更新,所以我做了add-migration <my migration>.但是,当它支持迁移时,它给了我已经应用到数据库的所有迁移的更改.所以:它试图删除已经删除的列,尝试创建一个已经存在的表,等等.

怎么可能?我的假设是EF只是检查_MigrationsHistory表格并找出表格中没有的迁移,并按名称的时间戳顺序应用这些迁移.但显然不是,因为即使我撤消自己的更改并且我有一个干净的环境,它仍然抱怨我的数据库与模型不同步.但我只是将这些更改删除并应用到我的数据库中.它同步的.我也可以看到我刚才在_MigrationsHistory表格中应用的迁移.

我唯一能想到的是我在一个不会导致数据库更改的数据模型中添加了一个属性(我List<X>在数据模型中添加了一个Y,其中X是一对多关系中的多个.这不会导致数据库更改,因为X已经有一个外键到Y).可能是吗?如果是这样,那真的很脆弱,因为没有办法为此添加迁移,因为没有数据库更改,我也不知道如何解决这个问题.

我不知道如何处理这个问题,因为我当然可以编辑它所支撑的内容并删除已经应用于我的数据库的所有内容.但那又怎样?我检查它然后其他一些开发人员得到相同的消息,即使他的数据库不适用于我的新更改,支持他自己的更改,获取相同的无意义脚手架,编辑它,检查它然后下一个开发者得到它.它变成了一个恶性循环,与我们使用自动迁移时的情况类似,我认为我们已经通过切换到基于代码的方式来解决这个问题.我现在不能相信做正确的事情,这样做是一场噩梦.

我也尝试过添加我从同事那里逐一删除的迁移,update-database -t:201211091112102_<migrationname>但无济于事.它仍然给我错误的脚手架.

那么我们在这里做错了什么,或者EF根本不是为这样的协作而构建的?

UPDATE

我创建了一个可重现的测试用例,虽然为了模拟这个多用户/多数据库场景,它有点冗长的舞蹈.

https://github.com/JulianR/EfMigrationsTest/

有上述项目时重现的步骤(这些步骤也出现在代码中):

  1. add-migration Init
  2. update-database(在数据库'TestDb'上)
  3. 将连接字符串更改为指向TestDb1
  4. TestDb1上的update-database
  5. 在类Test上取消注释属性Foo
  6. add-migration M1将属性Foo添加到TestDb1
  7. 再次评论Test.Foo
  8. 将连接字符串更改为指向TestDb2
  9. 从项目中排除迁移M1,因此它不会应用于TestDb2
  10. 在类Test上取消注释属性Bar
  11. update-database将Init迁移应用于TestDb2
  12. add-migration M2将属性Bar添加到TestDb2
  13. 将连接字符串更改为再次指向原始TestDb
  14. 将迁移M1再次包含到项目中
  15. 在类Test上取消注释属性Foo
  16. 在类Test上取消注释属性SomeInt
  17. 更新数据库
  18. 添加迁移M3
  19. update-database,因为M3尝试将列Foo添加到已经由迁移M1添加的数据库TestDb中而获得错误.

以上是模拟三个用户,其中用户1进入他的数据库,另外两个用户也使用他的初始化来创建他们的数据库.然后,用户2和用户3都对数据模型进行自己的更改,并将其与应用更改所需的迁移一起添加到源控件.然后,用户1拉动用户2和3的更改,而用户1也自己对数据库进行了更改.然后,用户1调用update-database以应用用户2和3的更改.然后,他自己进行迁移,然后错误地将用户2或3的更改添加到脚手架迁移,这会在应用于用户1的数据库时导致错误.

c# migration collaboration entity-framework ef-migrations

44
推荐指数
3
解决办法
8378
查看次数

为什么公共领域比属性更快?

我在XNA中闲逛,发现其中的Vector3类是使用公共字段而不是属性.我尝试了一个快速的基准测试,并发现,struct差异非常大(将两个向量组合在一起,1亿次带有2.0s属性和1.4s带字段).对于参考类型,差异似乎并不大,但它存在.

那为什么呢?我知道属性被编译成get_Xset_X方法,这会导致方法调用开销.但是,这些简单的getter/setter是不是总是被JIT内联?我知道你无法保证JIT决定做什么,但肯定这在概率列表中相当高?还有什么将公共领域与机器级别的财产分开?

有一点我一直想知道:自动实现的属性(public int Foo { get; set; })比公共领域"更好"的OO设计?或者更好地说:那两个有什么不同?我知道用反射把它变成一个属性更容易,但其他什么呢?我打赌这两个问题的答案是一回事.

BTW:我使用.NET 3.5 SP1,我相信固定的问题,其中有结构的方法(或方法结构,我不知道)均未成行,所以这不是它.我认为我至少使用它,它肯定安装但是再次,我使用Vista 64位SP1应该有DX10.1,除了我没有DX10.1 ..

另外:是的,我一直在运行发布版本:)

编辑:我很欣赏的快速解答的家伙,但我指出,我知道,一个属性访问是一个方法调用,但我不知道为什么,大概是,在林立的方法比直接字段访问速度较慢.

编辑2:所以我创建了另一个struct使用显式GetX()方法(o我怎么不完全错过我的Java时间),并且无论我是否禁用内嵌(通过),都执行相同的操作[MethodImplAttribute(MethodImplOptions.NoInlining)],所以结论:非静态方法显然从未内联,甚至不在结构上.

我认为有异常,JIT可以选择虚拟方法调用.为什么不能在没有继承的结构上发生这种情况,因此方法调用只能指向一种可能的方法,对吧?或者是因为你可以在它上面实现一个接口?

这是一种耻辱,因为它真的会让我考虑在性能关键的东西上使用属性,但使用字段会让我觉得很脏,我不妨写下我在C中做的事情.

编辑3:我发现这篇文章的主题完全相同.他的最终结论是,财产电话确实被优化了.我也可以发誓我已经多次阅读过简单的getter/setter属性会被内联,尽管callvirt在IL中.我疯了吗?

编辑4:Reed Copsey在下面的评论中发布了答案:

Re:Edit3 - 看我更新的评论:我相信这是x86 JIT vs x64 JIT问题.x64中的JIT不够成熟.随着越来越多的64位系统每天上线,我希望MS能够迅速提高. - 里德·科普塞

我回答他的回答:

谢谢,这就是答案!我尝试强制x86构建,所有方法都同样快,并且比x64快得多.实际上这对我来说非常令人震惊,我不知道我是在64位操作系统上生活在石器时代.我会在你的答案中包含你的评论,以便更好. - 朱利安

感谢大家!

c# oop struct properties public-fields

38
推荐指数
2
解决办法
7736
查看次数

什么时候结构的答案?

我正在做一个光线跟踪器爱好项目,最初我使用的是我的Vector和Ray对象的结构,我认为光线跟踪器是使用它们的完美情况:你创造了数百万个它们,它们的寿命不长于单个方法,它们很轻巧.但是,通过简单地在Vector和Ray上将'struct'更改为'class',我获得了非常显着的性能提升.

是什么赋予了?它们都很小(Vector为3个浮点数,Ray为2个向量),不要过度复制.当然,我确实将它们传递给方法,但这是不可避免的.那么在使用结构时会导致性能下降的常见缺陷是什么?我已阅读 MSDN文章,其中说明如下:

运行此示例时,您将看到struct循环的速度提高了几个数量级.但是,当您将ValueTypes视为对象时,请注意使用ValueTypes.这会给你的程序增加额外的装箱和拆箱开销,并且最终会比你坚持使用物品时花费更多!要查看此操作,请修改上面的代码以使用foos和bar数组.你会发现性能或多或少相等.

然而它已经很老了(2001年)而整个"把它们放在一个阵列导致拳击/拆箱"让我觉得奇怪.真的吗?但是,我确实预先计算了主光线并将它们放在一个数组中,所以我接受了这篇文章,并在我需要时计算了主光线并且从未将它们添加到数组中,但它没有改变任何东西:课程,它仍然快1.5倍.

我正在运行.NET 3.5 SP1,我相信修复了一个问题,即struct方法没有内联,所以也不可能.

所以基本上:任何提示,需要考虑的事项和避免的事项?

编辑:正如在一些答案中所建议的那样,我已经设置了一个测试项目,我尝试将结构作为参考传递.添加两个向量的方法:

public static VectorStruct Add(VectorStruct v1, VectorStruct v2)
{
  return new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}

public static VectorStruct Add(ref VectorStruct v1, ref VectorStruct v2)
{
  return new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}

public static void Add(ref VectorStruct v1, ref VectorStruct v2, out VectorStruct v3)
{
  v3 = new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}
Run Code Online (Sandbox Code Playgroud)

对于每个我得到以下基准方法的变体: …

c# performance struct raytracing struct-vs-class

32
推荐指数
6
解决办法
1万
查看次数

编译到委托表达式的性能

我正在生成一个表达式树,它将属性从源对象映射到目标对象,然后编译为a Func<TSource, TDestination, TDestination>并执行.

这是结果的调试视图LambdaExpression:

.Lambda #Lambda1<System.Func`3[MemberMapper.Benchmarks.Program+ComplexSourceType,MemberMapper.Benchmarks.Program+ComplexDestinationType,MemberMapper.Benchmarks.Program+ComplexDestinationType]>(
    MemberMapper.Benchmarks.Program+ComplexSourceType $right,
    MemberMapper.Benchmarks.Program+ComplexDestinationType $left) {
    .Block(
        MemberMapper.Benchmarks.Program+NestedSourceType $Complex$955332131,
        MemberMapper.Benchmarks.Program+NestedDestinationType $Complex$2105709326) {
        $left.ID = $right.ID;
        $Complex$955332131 = $right.Complex;
        $Complex$2105709326 = .New MemberMapper.Benchmarks.Program+NestedDestinationType();
        $Complex$2105709326.ID = $Complex$955332131.ID;
        $Complex$2105709326.Name = $Complex$955332131.Name;
        $left.Complex = $Complex$2105709326;
        $left
    }
}
Run Code Online (Sandbox Code Playgroud)

清理它将是:

(left, right) =>
{
    left.ID = right.ID;
    var complexSource = right.Complex;
    var complexDestination = new NestedDestinationType();
    complexDestination.ID = complexSource.ID;
    complexDestination.Name = complexSource.Name;
    left.Complex = complexDestination;
    return left;
}
Run Code Online (Sandbox Code Playgroud)

这是映射这些类型的属性的代码:

public class NestedSourceType
{
  public int ID …
Run Code Online (Sandbox Code Playgroud)

c# performance expression-trees dynamically-generated

31
推荐指数
1
解决办法
6770
查看次数

单击C#中的按钮显示新表单

我是C#的新手,任何人都可以告诉我如何在点击按钮时显示新表格.

c# winforms

24
推荐指数
3
解决办法
14万
查看次数

readonly是否有任何运行时开销?

出于某种原因,我一直认为readonly字段有与它们相关的开销,我认为这是CLR跟踪readonly字段是否已经初始化.这里的开销是一些额外的内存使用量来跟踪状态并在分配值时进行检查.

也许我假设这是因为我不知道一个readonly字段只能在构造函数内或字段声明本身内初始化,并且没有运行时检查,你将无法保证它不被多次分配给各种方法.但是现在我知道了,它可以很容易地被C#编译器静态检查,对吧?那是这样的吗?

另一个原因是,我已经读过使用readonly具有"轻微"性能影响,但他们从未涉及此声明,我无法找到有关此主题的信息,因此我的问题.我不知道除了运行时检查之外还有什么其他性能影响.

第三个原因是我看到它readonly在编译的IL 中被保留为initonly,所以这个信息在IL中的原因readonly是什么,如果只是C#编译器的保证,该字段永远不会分配给构造函数或声明?

另一方面,我发现你可以在readonly int没有CLR抛出异常的情况下设置通过反射的值,如果readonly是运行时检查则不可能.

所以我的猜测是:'readonlyness'只是一个编译时功能,任何人都可以确认/否认这个吗?如果是,那么这些信息被包含在IL中的原因是什么?

c# performance readonly immutability

18
推荐指数
2
解决办法
2339
查看次数

.NET:从动态程序集中访问非公共成员

我正在开发一个允许用户输入任意表达式的库.然后,我的库将这些表达式作为更大表达式的一部分编译到委托中.现在,由于仍然未知的原因,Compile有时/经常编译表达式导致代码远远低于它不是编译表达式时的代码.之前我问了一个关于这个的问题,一个解决方法是不使用Compile,但是在新的动态程序集中CompileToMethod创建static一个新类型的方法.这工作,代码很快.

但是用户可以输入任意表达式,结果是如果用户调用非公共函数或访问表达式中的非公共字段,则System.MethodAccessException在调用委托时抛出(在非公共方法的情况下) .

我可以在这里做的是创建一个新的ExpressionVisitor,检查表达式是否访问非公共的东西,并Compile在这些情况下使用较慢的,但我宁愿让动态程序集以某种方式获得访问非公共成员的权限.或者找出我能做些什么Compile来减慢速度(有时候).

重现此问题的完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;

namespace DynamicAssembly
{
  public class Program
  {
    private static int GetValue()
    {
      return 1;
    }

    public static int GetValuePublic()
    {
      return 1;
    }

    public static int Foo;

    static void Main(string[] args)
    {
      Expression<Func<int>> expression = () => 10 + GetValue();

      Foo = expression.Compile()(); …
Run Code Online (Sandbox Code Playgroud)

.net c# performance expression-trees dynamic-assemblies

18
推荐指数
1
解决办法
2799
查看次数

Mysql性能在600万行表上

有一天,我怀疑我必须学习hadoop并将所有这些数据传输到非结构化数据库,但我很惊讶地发现性能在如此短的时间内显着降低.

我有一个不到600万行的mysql表.我正在对这个表做一个非常简单的查询,并且相信我已经准备好了所有正确的索引.

查询是

SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date

解释返回

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  updateshows     range   date_idx    date_idx    7   NULL    648997  Using where

所以我尽可能使用正确的索引,但这个查询需要11秒才能运行.

数据库是MyISAM,phpMyAdmin表示表是1.0GiB.

这里有什么想法?

编辑:date_idx是日期和静脉列的索引.那些应该是两个单独的索引吗?

mysql indexing performance

16
推荐指数
1
解决办法
3万
查看次数

ASP.NET MVC的分页解决方案是否在数据库中进行分页?

我通过google搜索找到的大多数ASP.NET MVC分页解决方案看起来都是以IEnumerable集合的形式从数据库表中获取所有行,对IEnumerable集合执行一些分页转换,然后将结果返回给视图.我希望能够在数据库端进行分页,但仍然有一些分页类来进行页码计算和HTML生成.那里有解决办法吗?或者是我一直在寻找的那些,但我没有看到它,因为我看错了他们?

这是我一直在看的东西:

database asp.net-mvc paging pagination linq-to-sql

13
推荐指数
2
解决办法
5619
查看次数

C#:将指针类型用作字段?

在C#中,可以声明一个具有指针类型成员的结构(或类),如下所示:

unsafe struct Node
{
  public Node* NextNode;
}
Run Code Online (Sandbox Code Playgroud)

它是否安全(错误......忽略了那个具有讽刺意味的unsafe小旗......)使用这种结构?我的意思是在堆上长期存储.根据我的理解,GC可以自由移动,当它更新对已被移动的内容的引用时,它是否也更新了指针?我猜不是,这会使这种结构非常不安全,对吧?

我确信这样做有更好的选择,但称之为病态的好奇心.

编辑:似乎有些混乱.我知道这不是一个伟大的结构,我纯粹想知道这是否是一个安全的结构,即:指针保证指向你最初指向它的东西?

原始C代码用于遍历树(深度优先)而不递归,其中树存储在数组中.然后通过递增指针遍历数组,除非满足某个条件,然后将指针设置为NextNode,其中遍历继续.当然,在C#中也可以通过以下方式实现:

struct Node
{
  public int NextNode;
  ... // other fields
}
Run Code Online (Sandbox Code Playgroud)

其中int是下一个节点的数组中的索引.但出于性能原因,我最终会摆弄指针和fixed数组以避免边界检查,而原始的C代码似乎更自然.

c# pointers unsafe

12
推荐指数
1
解决办法
2467
查看次数