我喜欢LINQ to SQL,但似乎它生成的类与它们存储的数据库紧密耦合,这看起来像是一件坏事。
例如,使用ye olde Northwind数据库,如果我使用Products表创建dbml,则会生成Product
类。我可以在任何其他层使用此类,这一切都很好,但如果我决定使用普通的旧ADO.NET(或交换机数据库),我将不得不重新创建Product
类,以及其他所有“模特”。
有解决方法吗?或者单独创建对象模型,然后将表映射到它们?我已经玩过提供的各种地图类,但还没有找到满意的答案。
答案 0 :(得分:6)
所有这些答案都没有链接!也许我可以帮忙:
The attributes thing that damieng mentioned
The partial class thing that Marcus King mentioned
我已经厌倦了这个困难了几次,我最后在上一个项目中做的是使用接口作为在解决方案中所有不同项目之间共享的契约,并让部分类实现它。 / p>
[Table(Name="Products")]
public partial class Product: IProduct { }
是的,不幸的是,它需要一些反思才能使其适用于POCO实施。
最后,如果你真正关心它,我会选择NHibernate(我也不喜欢它),这正是Garry Shulter所描述的。
希望有所帮助!
答案 1 :(得分:3)
我的团队最近与这个问题进行了斗争。我真的很想保持“持久性无知”,这意味着域对象可以创建为普通的旧C#对象,而不必强制从某个基类继承或者用一堆属性来混淆类。就像你说的那样,我们希望能够独立于业务模型修改持久层。
最后,如果你想要持久性无知,我们认为LINQ不是可行的方法。我们最终编写了太多的映射代码,以便在LINQ层和业务层之间进行转换。当我们开始编写一堆基于反射的代码来尝试自动执行这些映射时,我们意识到我们正在滑下兔子洞,几乎没有显示它。
如果持久性无知对您很重要,那么您可能会更好地使用像NHIbernate这样的完整ORM。
答案 2 :(得分:2)
Linq to SQL(或EF)不关于持久性 - 无知。它是关于数据的对象视图。
NHibernate是你可能正在寻找的持久性 - 无知的ORM。
答案 3 :(得分:2)
我最近通过自己创建POCO并手动为数据库创建XML映射文件来实现这一目标。它需要一些手动工作,但它会产生预期的效果。
这是一个blog post I found useful来帮助您入门。
答案 4 :(得分:2)
哦,嘿,我想我在观看Rob Conery's screencasts on ASP.NET MVC时找到了解决方法。诀窍是select
进入LINQ to SQL查询中的对象。
public IQueryable<LinqExample.Core.Person> GetAll() {
var people = from pe in this.db.Persons
select new Person {
Id = pe.id,
FirstName = pe.fname,
LastName = pe.lname,
Reports = this.GetReports(pe.id)
};
return people;
}
这是让你在代码的其他地方定义一个Person
类。 I blogged about it更深入。
答案 5 :(得分:1)
Scott Hanselman做了一个关于asp.net DynamicData的屏幕,他使用了Linq To Sql类。虽然他没有解决这个问题,但我认为一般概念仍然可行。他的方法是创建一个单独的部分类,它与您的情况下的类Product
同名,由dbml生成。那么你应该总是有一个Product
类,它存在于LINQ生成的范围之外,只是“扩展”它的作用。
答案 6 :(得分:0)
只需将生成的代码复制到您自己的类中,然后关闭代码生成。神奇的属性不是别的。
或者,您可以编写自己的没有属性的纯CLR对象,并使用外部XML映射文件来描述对象与数据库之间的关系。可以在MSDN上的LINQ to SQL文档中找到更多信息。