我有几个从“用户”表到“报告”表的导航属性。生成的导航属性显然是这样访问的:
USER.REPORTs.Where(x => ...)
USER.REPORTs2.Where(x => ...)
USER.REPORTs3.Where(x => ...)
第一个是用户createdId,第二个是UserApprovedId等......基本的东西。
这些很难解释。如果不访问EDMX并检查导航属性,很难判断您正在导航哪个属性。
现在我知道我可以在属性管理器中创建自己的End1 / End2导航属性,但是如果重新创建模型,这些属性就会丢失。
有解决方法吗?
答案 0 :(得分:5)
我没有尝试过这个,但是这里有一个想法:因为所有实体类型都是部分类,为什么不将Visual Studio生成的导航属性包装在另一个具有方便名称的属性中?
在您的设计器文件中,您将拥有以下内容:
public partial class MyEntity : EntityObject
{
#region Navigation Properties
public EntityCollection<MyOtherEntity> Other_Entities1
{
// ...
}
#endregion
}
然后,您可以创建另一个文件来包装导航属性:
public partial class MyEntity
{
public EntityCollection<MyOtherEntity> OtherEntities
{
get { return Other_Entities1;}
}
}
您将在整个代码中使用上面的属性,因为当Visual Studio生成.edmx
文件时,使用相同的逻辑,包装属性不会更改。
即使包装属性将更改其名称,您也需要在一个位置调整代码。
答案 1 :(得分:1)
我不确定我是否正确理解您的问题,但听起来您只是想要一种“更清洁”的方式来直接从USER对象访问REPORTs.Where(...)LINQ查询的结果。如果是这种情况,我建议像这样创建USER对象的扩展名:
public static class UserExtensions
{
public static List<REPORT> ReportsWithSomeCondition(this USER user)
{
return user.REPORTs.Where(...).ToList();
}
}
你可以干净地称之为:
List<REPORT> results = USER.ReportsWithSomeCondition()
如果我完全忽略了这一点,请澄清您的问题,我将删除此答案。
答案 2 :(得分:1)
我认为我遇到了与你的问题相同的问题。
您希望尽可能清晰地保存导航属性名称,但每当从edmx重新创建模型时都会这样做?!
实际上我希望如果有更好的解决方案,但在这里我正在做的事情:
FK_Users_CreateUserReport
,FK_Users_ApprovedUserReport
...或任何合适的名称我们会将导航属性重命名为ApprovedUserReport
和{{1}所以...... 每当您重新创建模型时都会执行一个帮助程序代码,此代码将打开您的edmx文件并更新您想要的所有导航属性:
CreateUserReport
最后,如果你使用Code Only模式,那么这个问题就消失了,但在这种情况下,你应该让你的模型与你的DataBase保持一致。
答案 3 :(得分:0)
您必须使用分部类机制将所有自定义实体代码放在单独的代码文件中。这样可以生成生成的代码,而不会影响您的自定义代码。
答案 4 :(得分:0)
瓦希德的回答似乎是长期维持的最佳答案。我们考虑在Partial Class中实现接口属性,我们将其用作扩展和设置元数据链接的“Buddy类”。但是,我们接口的T4模板中的属性仍然是公开的,它们应该是私有的。
改善瓦希德的建议;我们选择而不是改变我们如何命名外键关系的标准,扩展它们。
FK_Users_Report_CreateUserReport实际上是我们的解决方案。保留前2个值的标准命名约定,并且在更新模型代码中,您可以强制它仅更改其上具有第3个下划线和第3个值的导航属性名称。如果不遵循DB中外键的标准命名约定,请确保不影响任何其他导航属性名称。